[Nouveau] [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running
Maarten Maathuis
madman2003 at gmail.com
Mon Feb 1 14:28:12 PST 2010
If there are no objections, please share them as soon as possible.
On Mon, Feb 1, 2010 at 7:40 PM, Maarten Maathuis <madman2003 at gmail.com> wrote:
> Someone should probably check this out on earlier cards as well.
>
> On Mon, Feb 1, 2010 at 7:34 PM, Maarten Maathuis <madman2003 at gmail.com> wrote:
>> - We need to disable pgraph fifo access before checking the current channel,
>> otherwise we could still hit a running ctxprog.
>> - The writes to 0x400500 are already handled by pgraph->fifo_access and are
>> therefore redundant, moreover pgraph fifo access should not be reenabled before
>> current context is set as invalid. So remove them altogether.
>>
>> Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
>> ---
>> drivers/gpu/drm/nouveau/nouveau_channel.c | 7 +++----
>> drivers/gpu/drm/nouveau/nv50_graph.c | 10 +++++++---
>> 2 files changed, 10 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> index 343d718..2281f99 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_channel.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> @@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
>> /* Ensure the channel is no longer active on the GPU */
>> pfifo->reassign(dev, false);
>>
>> - if (pgraph->channel(dev) == chan) {
>> - pgraph->fifo_access(dev, false);
>> + pgraph->fifo_access(dev, false);
>> + if (pgraph->channel(dev) == chan)
>> pgraph->unload_context(dev);
>> - pgraph->fifo_access(dev, true);
>> - }
>> pgraph->destroy_context(chan);
>> + pgraph->fifo_access(dev, true);
>>
>> if (pfifo->channel_id(dev) == chan->id) {
>> pfifo->disable(dev);
>> diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
>> index 20319e5..6d50480 100644
>> --- a/drivers/gpu/drm/nouveau/nv50_graph.c
>> +++ b/drivers/gpu/drm/nouveau/nv50_graph.c
>> @@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev)
>> uint32_t inst;
>> int i;
>>
>> + /* Be sure we're not in the middle of a context switch or bad things
>> + * will happen, such as unloading the wrong pgraph context.
>> + */
>> + if (!nv_wait(0x400300, 0x00000001, 0x00000000))
>> + NV_ERROR(dev, "Ctxprog is still running\n");
>> +
>> inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>> if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>> return NULL;
>> @@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
>> int
>> nv50_graph_unload_context(struct drm_device *dev)
>> {
>> - uint32_t inst, fifo = nv_rd32(dev, 0x400500);
>> + uint32_t inst;
>>
>> inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>> if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>> @@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev)
>> inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
>>
>> nouveau_wait_for_idle(dev);
>> - nv_wr32(dev, 0x400500, fifo & ~1);
>> nv_wr32(dev, 0x400784, inst);
>> nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
>> nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
>> nouveau_wait_for_idle(dev);
>> - nv_wr32(dev, 0x400500, fifo);
>>
>> nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
>> return 0;
>> --
>> 1.6.6.1
>>
>>
>
More information about the Nouveau
mailing list