summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-06-24 19:00:26 +1000
committerBen Skeggs <skeggsb@gmail.com>2007-06-24 19:00:26 +1000
commit5f05cd7086c54bccf1c2f0b003b78a08dc55472a (patch)
tree766442869357193576599718ead4fddaa680021d
parent5d55b0655cb480b7d6ab4cf2467dac6dc6d8df25 (diff)
nouveau: NV04/NV10/NV20 PGRAPH engtab functions
NV04/NV10 load_context()/save_context() are stubs. I don't know enough about how they work to implement them sanely. The "old" context_switch() code remains hooked up, so it shouldn't break anything. NV20 will probably break if load_context() works. No inital context values are filled in, so when the first channel is created PGRAPH will probably end up having its state zeroed. Some setup from nv20_graph_init() will probably need to be moved to the per-channel context setup.
-rw-r--r--shared-core/nouveau_drv.h21
-rw-r--r--shared-core/nouveau_fifo.c32
-rw-r--r--shared-core/nouveau_state.c12
-rw-r--r--shared-core/nv04_graph.c17
-rw-r--r--shared-core/nv10_graph.c17
-rw-r--r--shared-core/nv20_graph.c33
6 files changed, 86 insertions, 46 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index a4a37648..b3122d8a 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -275,21 +275,30 @@ extern int nv40_fifo_save_context(drm_device_t *, int channel);
/* nv04_graph.c */
extern void nouveau_nv04_context_switch(drm_device_t *dev);
-extern int nv04_graph_init(drm_device_t *dev);
+extern int nv04_graph_init(drm_device_t *dev);
extern void nv04_graph_takedown(drm_device_t *dev);
-extern int nv04_graph_context_create(drm_device_t *dev, int channel);
+extern int nv04_graph_create_context(drm_device_t *dev, int channel);
+extern void nv04_graph_destroy_context(drm_device_t *dev, int channel);
+extern int nv04_graph_load_context(drm_device_t *dev, int channel);
+extern int nv04_graph_save_context(drm_device_t *dev, int channel);
/* nv10_graph.c */
extern void nouveau_nv10_context_switch(drm_device_t *dev);
-extern int nv10_graph_init(drm_device_t *dev);
+extern int nv10_graph_init(drm_device_t *dev);
extern void nv10_graph_takedown(drm_device_t *dev);
-extern int nv10_graph_context_create(drm_device_t *dev, int channel);
+extern int nv10_graph_create_context(drm_device_t *dev, int channel);
+extern void nv10_graph_destroy_context(drm_device_t *dev, int channel);
+extern int nv10_graph_load_context(drm_device_t *dev, int channel);
+extern int nv10_graph_save_context(drm_device_t *dev, int channel);
/* nv20_graph.c */
extern void nouveau_nv20_context_switch(drm_device_t *dev);
-extern int nv20_graph_init(drm_device_t *dev);
+extern int nv20_graph_init(drm_device_t *dev);
extern void nv20_graph_takedown(drm_device_t *dev);
-extern int nv20_graph_context_create(drm_device_t *dev, int channel);
+extern int nv20_graph_create_context(drm_device_t *dev, int channel);
+extern void nv20_graph_destroy_context(drm_device_t *dev, int channel);
+extern int nv20_graph_load_context(drm_device_t *dev, int channel);
+extern int nv20_graph_save_context(drm_device_t *dev, int channel);
/* nv30_graph.c */
extern int nv30_graph_init(drm_device_t *dev);
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 1ef5a425..b47d4e0c 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -289,34 +289,10 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp)
NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
/* Create a graphics context for new channel */
- switch(dev_priv->card_type)
- {
- case NV_04:
- case NV_05:
- nv04_graph_context_create(dev, channel);
- break;
- case NV_10:
- case NV_17:
- nv10_graph_context_create(dev, channel);
- break;
- case NV_20:
- ret = nv20_graph_context_create(dev, channel);
- if (ret) {
- nouveau_fifo_free(dev, channel);
- return ret;
- }
- break;
- default:
- if (!engine->graph.create_context) {
- DRM_ERROR("graph.create_context == NULL\n");
- return DRM_ERR(EINVAL);
- }
- ret = engine->graph.create_context(dev, channel);
- if (ret) {
- nouveau_fifo_free(dev, channel);
- return ret;
- }
- break;
+ ret = engine->graph.create_context(dev, channel);
+ if (ret) {
+ nouveau_fifo_free(dev, channel);
+ return ret;
}
/* Construct inital RAMFC for new channel */
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index a997b075..b3562e2f 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -88,6 +88,10 @@ static int nouveau_init_engine_ptrs(drm_device_t *dev)
engine->fb.takedown = nv04_fb_takedown;
engine->graph.init = nv04_graph_init;
engine->graph.takedown = nv04_graph_takedown;
+ engine->graph.create_context = nv04_graph_create_context;
+ engine->graph.destroy_context = nv04_graph_destroy_context;
+ engine->graph.load_context = nv04_graph_load_context;
+ engine->graph.save_context = nv04_graph_save_context;
engine->fifo.init = nouveau_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
engine->fifo.create_context = nv04_fifo_create_context;
@@ -104,6 +108,10 @@ static int nouveau_init_engine_ptrs(drm_device_t *dev)
engine->fb.takedown = nv10_fb_takedown;
engine->graph.init = nv10_graph_init;
engine->graph.takedown = nv10_graph_takedown;
+ engine->graph.create_context = nv10_graph_create_context;
+ engine->graph.destroy_context = nv10_graph_destroy_context;
+ engine->graph.load_context = nv10_graph_load_context;
+ engine->graph.save_context = nv10_graph_save_context;
engine->fifo.init = nouveau_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
if (dev_priv->chipset < 0x17) {
@@ -127,6 +135,10 @@ static int nouveau_init_engine_ptrs(drm_device_t *dev)
engine->fb.takedown = nv10_fb_takedown;
engine->graph.init = nv20_graph_init;
engine->graph.takedown = nv20_graph_takedown;
+ engine->graph.create_context = nv20_graph_create_context;
+ engine->graph.destroy_context = nv20_graph_destroy_context;
+ engine->graph.load_context = nv20_graph_load_context;
+ engine->graph.save_context = nv20_graph_save_context;
engine->fifo.init = nouveau_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
engine->fifo.create_context = nv10_fifo_create_context;
diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c
index 0cd4d3b8..1aaae33c 100644
--- a/shared-core/nv04_graph.c
+++ b/shared-core/nv04_graph.c
@@ -336,7 +336,7 @@ void nouveau_nv04_context_switch(drm_device_t *dev)
NV_WRITE(NV04_PGRAPH_FIFO,0x1);
}
-int nv04_graph_context_create(drm_device_t *dev, int channel) {
+int nv04_graph_create_context(drm_device_t *dev, int channel) {
drm_nouveau_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("nv04_graph_context_create %d\n", channel);
@@ -351,6 +351,21 @@ int nv04_graph_context_create(drm_device_t *dev, int channel) {
return 0;
}
+void nv04_graph_destroy_context(drm_device_t *dev, int channel)
+{
+}
+
+int nv04_graph_load_context(drm_device_t *dev, int channel)
+{
+ DRM_ERROR("stub!\n");
+ return 0;
+}
+
+int nv04_graph_save_context(drm_device_t *dev, int channel)
+{
+ DRM_ERROR("stub!\n");
+ return 0;
+}
int nv04_graph_init(drm_device_t *dev) {
drm_nouveau_private_t *dev_priv = dev->dev_private;
diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c
index fb189709..d1fe0a54 100644
--- a/shared-core/nv10_graph.c
+++ b/shared-core/nv10_graph.c
@@ -611,7 +611,7 @@ void nouveau_nv10_context_switch(drm_device_t *dev)
if (offset > 0) \
fifo->pgraph_ctx[offset] = val; \
} while (0)
-int nv10_graph_context_create(drm_device_t *dev, int channel) {
+int nv10_graph_create_context(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;
@@ -663,6 +663,21 @@ int nv10_graph_context_create(drm_device_t *dev, int channel) {
return 0;
}
+void nv10_graph_destroy_context(drm_device_t *dev, int channel)
+{
+}
+
+int nv10_graph_load_context(drm_device_t *dev, int channel)
+{
+ DRM_ERROR("stub!\n");
+ return 0;
+}
+
+int nv10_graph_save_context(drm_device_t *dev, int channel)
+{
+ DRM_ERROR("stub!\n");
+ return 0;
+}
int nv10_graph_init(drm_device_t *dev) {
drm_nouveau_private_t *dev_priv = dev->dev_private;
diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c
index 7190fc84..1b8a6727 100644
--- a/shared-core/nv20_graph.c
+++ b/shared-core/nv20_graph.c
@@ -29,7 +29,7 @@
#define NV20_GRCTX_SIZE (3529*4)
-int nv20_graph_context_create(drm_device_t *dev, int channel) {
+int nv20_graph_create_context(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];
@@ -47,10 +47,21 @@ int nv20_graph_context_create(drm_device_t *dev, int channel) {
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;
}
+void nv20_graph_destroy_context(drm_device_t *dev, int channel) {
+ drm_nouveau_private_t *dev_priv = dev->dev_private;
+ struct nouveau_fifo *chan = &dev_priv->fifos[channel];
+
+ if (chan->ramin_grctx) {
+ nouveau_instmem_free(dev, chan->ramin_grctx);
+ chan->ramin_grctx = NULL;
+ }
+
+ INSTANCE_WR(dev_priv->ctx_table, channel, 0);
+}
+
static void nv20_graph_rdi(drm_device_t *dev) {
drm_nouveau_private_t *dev_priv =
(drm_nouveau_private_t *)dev->dev_private;
@@ -65,40 +76,42 @@ static void nv20_graph_rdi(drm_device_t *dev) {
/* Save current context (from PGRAPH) into the channel's context
*/
-static void nv20_graph_context_save_current(drm_device_t *dev, int channel) {
+int nv20_graph_save_context(drm_device_t *dev, int channel) {
drm_nouveau_private_t *dev_priv =
(drm_nouveau_private_t *)dev->dev_private;
uint32_t instance;
instance = INSTANCE_RD(dev_priv->ctx_table, channel);
if (!instance) {
- return;
+ return DRM_ERR(EINVAL);
}
if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx))
- DRM_ERROR("nv20_graph_context_save_current : bad instance\n");
+ DRM_ERROR("nv20_graph_save_context : bad instance\n");
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance);
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 2 /* save ctx */);
+ return 0;
}
/* Restore the context for a specific channel into PGRAPH
*/
-static void nv20_graph_context_restore(drm_device_t *dev, int channel) {
+int nv20_graph_load_context(drm_device_t *dev, int channel) {
drm_nouveau_private_t *dev_priv =
(drm_nouveau_private_t *)dev->dev_private;
uint32_t instance;
instance = INSTANCE_RD(dev_priv->ctx_table, channel);
if (!instance) {
- return;
+ return DRM_ERR(EINVAL);
}
if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx))
- DRM_ERROR("nv20_graph_context_restore_current : bad instance\n");
+ DRM_ERROR("nv20_graph_load_context_current : bad instance\n");
NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24);
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance);
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 1 /* restore ctx */);
+ return 0;
}
void nouveau_nv20_context_switch(drm_device_t *dev)
@@ -113,13 +126,13 @@ void nouveau_nv20_context_switch(drm_device_t *dev)
NV_WRITE(NV04_PGRAPH_FIFO,0x0);
- nv20_graph_context_save_current(dev, channel_old);
+ nv20_graph_save_context(dev, channel_old);
nouveau_wait_for_idle(dev);
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000);
- nv20_graph_context_restore(dev, channel);
+ nv20_graph_load_context(dev, channel);
nouveau_wait_for_idle(dev);