drm/nv50: remove manual context unload on context destruction
PFIFO context destruction triggers this automagically now. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
7f2062e9de
Коммит
5511d490da
|
@ -39,45 +39,6 @@ struct nv50_graph_engine {
|
||||||
u32 grctx_size;
|
u32 grctx_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
nv50_graph_fifo_access(struct drm_device *dev, bool enabled)
|
|
||||||
{
|
|
||||||
const uint32_t mask = 0x00010001;
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask);
|
|
||||||
else
|
|
||||||
nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nouveau_channel *
|
|
||||||
nv50_graph_channel(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
|
||||||
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(dev, 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;
|
|
||||||
inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12;
|
|
||||||
|
|
||||||
for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
|
|
||||||
struct nouveau_channel *chan = dev_priv->channels.ptr[i];
|
|
||||||
|
|
||||||
if (chan && chan->ramin && chan->ramin->vinst == inst)
|
|
||||||
return chan;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
|
nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
|
||||||
{
|
{
|
||||||
|
@ -257,31 +218,13 @@ nv50_graph_context_del(struct nouveau_channel *chan, int engine)
|
||||||
struct drm_device *dev = chan->dev;
|
struct drm_device *dev = chan->dev;
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
|
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);
|
|
||||||
nv_wr32(dev, NV03_PFIFO_CACHES, 0);
|
|
||||||
nv50_graph_fifo_access(dev, false);
|
|
||||||
|
|
||||||
if (nv50_graph_channel(dev) == chan)
|
|
||||||
nv50_graph_unload_context(dev);
|
|
||||||
|
|
||||||
for (i = hdr; i < hdr + 24; i += 4)
|
for (i = hdr; i < hdr + 24; i += 4)
|
||||||
nv_wo32(chan->ramin, i, 0);
|
nv_wo32(chan->ramin, i, 0);
|
||||||
dev_priv->engine.instmem.flush(dev);
|
dev_priv->engine.instmem.flush(dev);
|
||||||
|
|
||||||
nv50_graph_fifo_access(dev, true);
|
|
||||||
nv_wr32(dev, NV03_PFIFO_CACHES, 1);
|
|
||||||
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
|
|
||||||
|
|
||||||
nouveau_gpuobj_ref(NULL, &grctx);
|
|
||||||
|
|
||||||
atomic_dec(&chan->vm->engref[engine]);
|
atomic_dec(&chan->vm->engref[engine]);
|
||||||
|
nouveau_gpuobj_ref(NULL, &grctx);
|
||||||
chan->engctx[engine] = NULL;
|
chan->engctx[engine] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,27 +77,13 @@ nv50_mpeg_context_new(struct nouveau_channel *chan, int engine)
|
||||||
static void
|
static void
|
||||||
nv50_mpeg_context_del(struct nouveau_channel *chan, int engine)
|
nv50_mpeg_context_del(struct nouveau_channel *chan, int engine)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
|
|
||||||
struct nouveau_gpuobj *ctx = chan->engctx[engine];
|
struct nouveau_gpuobj *ctx = chan->engctx[engine];
|
||||||
struct drm_device *dev = chan->dev;
|
struct drm_device *dev = chan->dev;
|
||||||
unsigned long flags;
|
int i;
|
||||||
u32 inst, i;
|
|
||||||
|
|
||||||
if (!chan->ramin)
|
|
||||||
return;
|
|
||||||
|
|
||||||
inst = chan->ramin->vinst >> 12;
|
|
||||||
inst |= 0x80000000;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
|
|
||||||
nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
|
|
||||||
if (nv_rd32(dev, 0x00b318) == inst)
|
|
||||||
nv_mask(dev, 0x00b318, 0x80000000, 0x00000000);
|
|
||||||
nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
|
|
||||||
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
|
|
||||||
|
|
||||||
for (i = 0x00; i <= 0x14; i += 4)
|
for (i = 0x00; i <= 0x14; i += 4)
|
||||||
nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000);
|
nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000);
|
||||||
|
|
||||||
nouveau_gpuobj_ref(NULL, &ctx);
|
nouveau_gpuobj_ref(NULL, &ctx);
|
||||||
chan->engctx[engine] = NULL;
|
chan->engctx[engine] = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,29 +79,13 @@ static void
|
||||||
nva3_copy_context_del(struct nouveau_channel *chan, int engine)
|
nva3_copy_context_del(struct nouveau_channel *chan, int engine)
|
||||||
{
|
{
|
||||||
struct nouveau_gpuobj *ctx = chan->engctx[engine];
|
struct nouveau_gpuobj *ctx = chan->engctx[engine];
|
||||||
struct drm_device *dev = chan->dev;
|
int i;
|
||||||
u32 inst;
|
|
||||||
|
|
||||||
inst = (chan->ramin->vinst >> 12);
|
for (i = 0xc0; i <= 0xd4; i += 4)
|
||||||
inst |= 0x40000000;
|
nv_wo32(chan->ramin, i, 0x00000000);
|
||||||
|
|
||||||
/* disable fifo access */
|
|
||||||
nv_wr32(dev, 0x104048, 0x00000000);
|
|
||||||
/* mark channel as unloaded if it's currently active */
|
|
||||||
if (nv_rd32(dev, 0x104050) == inst)
|
|
||||||
nv_mask(dev, 0x104050, 0x40000000, 0x00000000);
|
|
||||||
/* mark next channel as invalid if it's about to be loaded */
|
|
||||||
if (nv_rd32(dev, 0x104054) == inst)
|
|
||||||
nv_mask(dev, 0x104054, 0x40000000, 0x00000000);
|
|
||||||
/* restore fifo access */
|
|
||||||
nv_wr32(dev, 0x104048, 0x00000003);
|
|
||||||
|
|
||||||
for (inst = 0xc0; inst <= 0xd4; inst += 4)
|
|
||||||
nv_wo32(chan->ramin, inst, 0x00000000);
|
|
||||||
|
|
||||||
nouveau_gpuobj_ref(NULL, &ctx);
|
|
||||||
|
|
||||||
atomic_dec(&chan->vm->engref[engine]);
|
atomic_dec(&chan->vm->engref[engine]);
|
||||||
|
nouveau_gpuobj_ref(NULL, &ctx);
|
||||||
chan->engctx[engine] = ctx;
|
chan->engctx[engine] = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче