Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 228528
b: refs/heads/master
c: 3945e47
h: refs/heads/master
v: v3
  • Loading branch information
Francisco Jerez authored and Ben Skeggs committed Dec 3, 2010
1 parent 9d8ceab commit 38afece
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fcccab2e4eb8d579837481054cc2cb28eea0baef
refs/heads/master: 3945e47543863385b54d94c94b023ee7ca9df972
24 changes: 6 additions & 18 deletions trunk/drivers/gpu/drm/nouveau/nouveau_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,32 +313,20 @@ nouveau_channel_put(struct nouveau_channel **pchan)
/* boot it off the hardware */
pfifo->reassign(dev, false);

/* We want to give pgraph a chance to idle and get rid of all potential
* errors. We need to do this before the lock, otherwise the irq handler
* is unable to process them.
/* We want to give pgraph a chance to idle and get rid of all
* potential errors. We need to do this without the context
* switch lock held, otherwise the irq handler is unable to
* process them.
*/
if (pgraph->channel(dev) == chan)
nouveau_wait_for_idle(dev);

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);

pgraph->fifo_access(dev, false);
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);
pgraph->destroy_context(chan);
pgraph->fifo_access(dev, true);

if (pfifo->channel_id(dev) == chan->id) {
pfifo->disable(dev);
pfifo->unload_context(dev);
pfifo->enable(dev);
}
/* destroy the engine specific contexts */
pfifo->destroy_context(chan);
pgraph->destroy_context(chan);

pfifo->reassign(dev, true);

spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

/* aside from its resources, the channel should now be dead,
* remove it from the channel list
*/
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,14 +998,12 @@ extern int nv04_fifo_unload_context(struct drm_device *);
extern int nv10_fifo_init(struct drm_device *);
extern int nv10_fifo_channel_id(struct drm_device *);
extern int nv10_fifo_create_context(struct nouveau_channel *);
extern void nv10_fifo_destroy_context(struct nouveau_channel *);
extern int nv10_fifo_load_context(struct nouveau_channel *);
extern int nv10_fifo_unload_context(struct drm_device *);

/* nv40_fifo.c */
extern int nv40_fifo_init(struct drm_device *);
extern int nv40_fifo_create_context(struct nouveau_channel *);
extern void nv40_fifo_destroy_context(struct nouveau_channel *);
extern int nv40_fifo_load_context(struct nouveau_channel *);
extern int nv40_fifo_unload_context(struct drm_device *);

Expand Down
8 changes: 4 additions & 4 deletions trunk/drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
Expand Down Expand Up @@ -191,7 +191,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
Expand Down Expand Up @@ -245,7 +245,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv10_fifo_create_context;
engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
Expand Down Expand Up @@ -302,7 +302,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.cache_pull = nv04_fifo_cache_pull;
engine->fifo.channel_id = nv10_fifo_channel_id;
engine->fifo.create_context = nv40_fifo_create_context;
engine->fifo.destroy_context = nv40_fifo_destroy_context;
engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.load_context = nv40_fifo_load_context;
engine->fifo.unload_context = nv40_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
Expand Down
21 changes: 19 additions & 2 deletions trunk/drivers/gpu/drm/nouveau/nv04_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,27 @@ void
nv04_fifo_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
unsigned long flags;

nv_wr32(dev, NV04_PFIFO_MODE,
nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pfifo->reassign(dev, false);

/* Unload the context if it's the currently active one */
if (pfifo->channel_id(dev) == chan->id) {
pfifo->disable(dev);
pfifo->unload_context(dev);
pfifo->enable(dev);
}

/* Keep it from being rescheduled */
nv_mask(dev, NV04_PFIFO_MODE, 1 << chan->id, 0);

pfifo->reassign(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

/* Free the channel resources */
nouveau_gpuobj_ref(NULL, &chan->ramfc);
}

Expand Down
15 changes: 15 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv04_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,25 @@ int nv04_graph_create_context(struct nouveau_channel *chan)

void nv04_graph_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct graph_state *pgraph_ctx = chan->pgraph_ctx;
unsigned long flags;

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);

/* Unload the context if it's the currently active one */
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);

/* Free the context resources */
kfree(pgraph_ctx);
chan->pgraph_ctx = NULL;

pgraph->fifo_access(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
}

int nv04_graph_load_context(struct nouveau_channel *chan)
Expand Down
11 changes: 0 additions & 11 deletions trunk/drivers/gpu/drm/nouveau/nv10_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
return 0;
}

void
nv10_fifo_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;

nv_wr32(dev, NV04_PFIFO_MODE,
nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));

nouveau_gpuobj_ref(NULL, &chan->ramfc);
}

static void
nv10_fifo_do_load_context(struct drm_device *dev, int chid)
{
Expand Down
15 changes: 15 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv10_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,10 +875,25 @@ int nv10_graph_create_context(struct nouveau_channel *chan)

void nv10_graph_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct graph_state *pgraph_ctx = chan->pgraph_ctx;
unsigned long flags;

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);

/* Unload the context if it's the currently active one */
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);

/* Free the context resources */
kfree(pgraph_ctx);
chan->pgraph_ctx = NULL;

pgraph->fifo_access(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
}

void
Expand Down
14 changes: 13 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nv20_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,21 @@ nv20_graph_destroy_context(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
unsigned long flags;

nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);

/* Unload the context if it's the currently active one */
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);

pgraph->fifo_access(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

/* Free the context resources */
nv_wo32(pgraph->ctx_table, chan->id * 4, 0);
nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
}

int
Expand Down
11 changes: 0 additions & 11 deletions trunk/drivers/gpu/drm/nouveau/nv40_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
return 0;
}

void
nv40_fifo_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;

nv_wr32(dev, NV04_PFIFO_MODE,
nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id));

nouveau_gpuobj_ref(NULL, &chan->ramfc);
}

static void
nv40_fifo_do_load_context(struct drm_device *dev, int chid)
{
Expand Down
16 changes: 16 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv40_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ nv40_graph_create_context(struct nouveau_channel *chan)
void
nv40_graph_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
unsigned long flags;

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);

/* Unload the context if it's the currently active one */
if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);

pgraph->fifo_access(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

/* Free the context resources */
nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
}

Expand Down
17 changes: 17 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv50_fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,23 @@ void
nv50_fifo_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_gpuobj *ramfc = NULL;
unsigned long flags;

NV_DEBUG(dev, "ch%d\n", chan->id);

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pfifo->reassign(dev, false);

/* Unload the context if it's the currently active one */
if (pfifo->channel_id(dev) == chan->id) {
pfifo->disable(dev);
pfifo->unload_context(dev);
pfifo->enable(dev);
}

/* This will ensure the channel is seen as disabled. */
nouveau_gpuobj_ref(chan->ramfc, &ramfc);
nouveau_gpuobj_ref(NULL, &chan->ramfc);
Expand All @@ -306,6 +319,10 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan)
nv50_fifo_channel_disable(dev, 127);
nv50_fifo_playlist_update(dev);

pfifo->reassign(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

/* Free the channel resources */
nouveau_gpuobj_ref(NULL, &ramfc);
nouveau_gpuobj_ref(NULL, &chan->cache);
}
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv50_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,28 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
unsigned long flags;

NV_DEBUG(dev, "ch%d\n", chan->id);

if (!chan->ramin)
return;

spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
pgraph->fifo_access(dev, false);

if (pgraph->channel(dev) == chan)
pgraph->unload_context(dev);

for (i = hdr; i < hdr + 24; i += 4)
nv_wo32(chan->ramin, i, 0);
dev_priv->engine.instmem.flush(dev);

pgraph->fifo_access(dev, true);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);

nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
}

Expand Down

0 comments on commit 38afece

Please sign in to comment.