drm/nouveau/core: have fifo store a unique context identifier at attach time
authorBen Skeggs <bskeggs@redhat.com>
Fri, 10 Aug 2012 05:10:34 +0000 (15:10 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 3 Oct 2012 03:13:03 +0000 (13:13 +1000)
This value will match something that's easily available from the engine IRQ
handlers, and used to lookup the relevant context.

Since the changes in how this is done on each generation match when the
major PFIFO changes happened, fifo is responsible for calculating the
correct value to avoid duplicating the same code among many engine modules.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/core/engctx.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
drivers/gpu/drm/nouveau/core/include/core/engctx.h
drivers/gpu/drm/nouveau/core/include/engine/fifo.h

index 38c0612a5122e49db9ab46ea75b792b9a5da202c..ad4bbe106b0efc307bd92831965fcc5b44137684 100644 (file)
@@ -105,6 +105,7 @@ nouveau_engctx_create_(struct nouveau_object *parent,
        if (client->vm)
                atomic_inc(&client->vm->engref[nv_engidx(engobj)]);
        list_add(&nv_engctx(engctx)->head, &engine->contexts);
+       nv_engctx(engctx)->addr = ~0ULL;
        spin_unlock_irqrestore(&engine->lock, save);
        return 0;
 }
index 8b7513f4dc8f214827a5a1ddae73cd9f3f9e2ab1..7cd5d76dad29172a972712e4c8b728ffa7e2aaf8 100644 (file)
@@ -102,6 +102,14 @@ nv04_fifo_object_detach(struct nouveau_object *parent, int cookie)
        mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
+int
+nv04_fifo_context_attach(struct nouveau_object *parent,
+                        struct nouveau_object *object)
+{
+       nv_engctx(object)->addr = nouveau_fifo_chan(parent)->chid;
+       return 0;
+}
+
 static int
 nv04_fifo_chan_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
@@ -127,6 +135,7 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent,
 
        nv_parent(chan)->object_attach = nv04_fifo_object_attach;
        nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+       nv_parent(chan)->context_attach = nv04_fifo_context_attach;
        chan->ramfc = chan->base.chid * 32;
 
        nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
index 391fefa7c472c24e61f9da507d72195bfde83aec..5d3638bddb8bbd96c168a6eaaad864d5c1e2f44a 100644 (file)
@@ -78,6 +78,7 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent,
 
        nv_parent(chan)->object_attach = nv04_fifo_object_attach;
        nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+       nv_parent(chan)->context_attach = nv04_fifo_context_attach;
        chan->ramfc = chan->base.chid * 32;
 
        nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
index 3b9d6c97f9bab8e51af70d59b9d7fb689b2965db..f223eb9c773c78b8ddc3f43028981ea2d84fff56 100644 (file)
@@ -85,6 +85,7 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent,
 
        nv_parent(chan)->object_attach = nv04_fifo_object_attach;
        nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+       nv_parent(chan)->context_attach = nv04_fifo_context_attach;
        chan->ramfc = chan->base.chid * 64;
 
        nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
index 43d5c9eea8654eb8d268f7541cc5225bcdc79656..ce97c5ee4658c2cf0c7d266e304600a4389245ee 100644 (file)
@@ -128,11 +128,12 @@ nv40_fifo_context_attach(struct nouveau_object *parent,
        }
 
        spin_lock_irqsave(&priv->base.lock, flags);
+       nv_engctx(engctx)->addr = nv_gpuobj(engctx)->addr >> 4;
        nv_mask(priv, 0x002500, 0x00000001, 0x00000000);
 
        if ((nv_rd32(priv, 0x003204) & priv->base.max) == chan->base.chid)
-               nv_wr32(priv, reg, nv_gpuobj(engctx)->addr >> 4);
-       nv_wo32(priv->ramfc, chan->ramfc + ctx, nv_gpuobj(engctx)->addr >> 4);
+               nv_wr32(priv, reg, nv_engctx(engctx)->addr);
+       nv_wo32(priv->ramfc, chan->ramfc + ctx, nv_engctx(engctx)->addr);
 
        nv_mask(priv, 0x002500, 0x00000001, 0x00000001);
        spin_unlock_irqrestore(&priv->base.lock, flags);
index 5b80f3e10a6fcfbdf3bdf9e337f1b8498a7462a5..452f2241783af3eef27d98593c576663dcf09704 100644 (file)
@@ -81,6 +81,7 @@ nv50_fifo_context_attach(struct nouveau_object *parent,
                return -EINVAL;
        }
 
+       nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
        nv_wo32(base->eng, addr + 0x00, 0x00190000);
        nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
        nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
index 694a9bbaa02f894a58e453d78a5b5a465abc8cb1..80c39270b5896a639bfd729d73436ac05d3dadea 100644 (file)
@@ -62,6 +62,7 @@ nv84_fifo_context_attach(struct nouveau_object *parent,
                return -EINVAL;
        }
 
+       nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
        nv_wo32(base->eng, addr + 0x00, 0x00190000);
        nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
        nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
index a4ae2bfd6035ccb0089d47168b24179ed5ed81fc..d10dca237ca35dd2bbe0a61911b428e7a56e495e 100644 (file)
@@ -112,6 +112,8 @@ nvc0_fifo_context_attach(struct nouveau_object *parent,
                                            NV_MEM_ACCESS_RW, &ectx->vma);
                if (ret)
                        return ret;
+
+               nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
        }
 
        nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
index c3f4955fef563fb744711ef76c97c308a9c189a3..042afadbdf2ec2038d9be06ebffd30c5809625a8 100644 (file)
@@ -147,6 +147,8 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
                                            NV_MEM_ACCESS_RW, &ectx->vma);
                if (ret)
                        return ret;
+
+               nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
        }
 
        nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
index 3bc6ccd6cbd8d1942c138f5924de9efecf4436ce..227b2c190f1c9f35f15721d1e287145f2d866fac 100644 (file)
@@ -13,6 +13,7 @@ struct nouveau_engctx {
        struct nouveau_gpuobj base;
        struct nouveau_vma vma;
        struct list_head head;
+       u64 addr;
 };
 
 static inline struct nouveau_engctx *
index f2133872bd7c9d20f13ba83c39b587b456261293..d67fed1e39702e572b61e8c0bdb0658e0fe1ca4f 100644 (file)
@@ -106,5 +106,6 @@ extern struct nouveau_oclass nvc0_fifo_oclass;
 extern struct nouveau_oclass nve0_fifo_oclass;
 
 void nv04_fifo_intr(struct nouveau_subdev *);
+int  nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
 
 #endif