diff options
| author | Ben Skeggs <skeggsb@gmail.com> | 2007-06-24 19:00:26 +1000 | 
|---|---|---|
| committer | Ben Skeggs <skeggsb@gmail.com> | 2007-06-24 19:00:26 +1000 | 
| commit | 5f05cd7086c54bccf1c2f0b003b78a08dc55472a (patch) | |
| tree | 766442869357193576599718ead4fddaa680021d | |
| parent | 5d55b0655cb480b7d6ab4cf2467dac6dc6d8df25 (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.h | 21 | ||||
| -rw-r--r-- | shared-core/nouveau_fifo.c | 32 | ||||
| -rw-r--r-- | shared-core/nouveau_state.c | 12 | ||||
| -rw-r--r-- | shared-core/nv04_graph.c | 17 | ||||
| -rw-r--r-- | shared-core/nv10_graph.c | 17 | ||||
| -rw-r--r-- | shared-core/nv20_graph.c | 33 | 
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); | 
