mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-27 11:40:11 +01:00
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.
This commit is contained in:
parent
5d55b0655c
commit
5f05cd7086
6 changed files with 86 additions and 46 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue