summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv84_crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_crypt.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv84_crypt.c122
1 files changed, 76 insertions, 46 deletions
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
index 4918f4e60ba..75b809a5174 100644
--- a/drivers/gpu/drm/nouveau/nv84_crypt.c
+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
@@ -28,45 +28,46 @@
#include "nouveau_vm.h"
#include "nouveau_ramht.h"
-static void nv84_crypt_isr(struct drm_device *);
+struct nv84_crypt_engine {
+ struct nouveau_exec_engine base;
+};
-int
-nv84_crypt_create_context(struct nouveau_channel *chan)
+static int
+nv84_crypt_context_new(struct nouveau_channel *chan, int engine)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *ramin = chan->ramin;
+ struct nouveau_gpuobj *ctx;
int ret;
NV_DEBUG(dev, "ch%d\n", chan->id);
- ret = nouveau_gpuobj_new(dev, chan, 256, 0,
- NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
- &chan->crypt_ctx);
+ ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ZERO_FREE, &ctx);
if (ret)
return ret;
nv_wo32(ramin, 0xa0, 0x00190000);
- nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff);
- nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst);
+ nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
+ nv_wo32(ramin, 0xa8, ctx->vinst);
nv_wo32(ramin, 0xac, 0);
nv_wo32(ramin, 0xb0, 0);
nv_wo32(ramin, 0xb4, 0);
-
dev_priv->engine.instmem.flush(dev);
- atomic_inc(&chan->vm->pcrypt_refs);
+
+ atomic_inc(&chan->vm->engref[engine]);
+ chan->engctx[engine] = ctx;
return 0;
}
-void
-nv84_crypt_destroy_context(struct nouveau_channel *chan)
+static void
+nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
{
+ struct nouveau_gpuobj *ctx = chan->engctx[engine];
struct drm_device *dev = chan->dev;
u32 inst;
- if (!chan->crypt_ctx)
- return;
-
inst = (chan->ramin->vinst >> 12);
inst |= 0x80000000;
@@ -81,12 +82,15 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan)
nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
nv_wr32(dev, 0x10200c, 0x00000010);
- nouveau_gpuobj_ref(NULL, &chan->crypt_ctx);
- atomic_dec(&chan->vm->pcrypt_refs);
+ nouveau_gpuobj_ref(NULL, &ctx);
+
+ atomic_dec(&chan->vm->engref[engine]);
+ chan->engctx[engine] = NULL;
}
-int
-nv84_crypt_object_new(struct nouveau_channel *chan, u32 handle, u16 class)
+static int
+nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
+ u32 handle, u16 class)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -107,27 +111,45 @@ nv84_crypt_object_new(struct nouveau_channel *chan, u32 handle, u16 class)
return ret;
}
-void
-nv84_crypt_tlb_flush(struct drm_device *dev)
+static void
+nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
{
nv50_vm_flush_engine(dev, 0x0a);
}
-int
-nv84_crypt_init(struct drm_device *dev)
+static void
+nv84_crypt_isr(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
+ u32 stat = nv_rd32(dev, 0x102130);
+ u32 mthd = nv_rd32(dev, 0x102190);
+ u32 data = nv_rd32(dev, 0x102194);
+ u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
+ int show = nouveau_ratelimit();
- if (!pcrypt->registered) {
- NVOBJ_CLASS(dev, 0x74c1, CRYPT);
- pcrypt->registered = true;
+ if (show) {
+ NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ stat, mthd, data, inst);
}
+ nv_wr32(dev, 0x102130, stat);
+ nv_wr32(dev, 0x10200c, 0x10);
+
+ nv50_fb_vm_trap(dev, show);
+}
+
+static int
+nv84_crypt_fini(struct drm_device *dev, int engine)
+{
+ nv_wr32(dev, 0x102140, 0x00000000);
+ return 0;
+}
+
+static int
+nv84_crypt_init(struct drm_device *dev, int engine)
+{
nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
- nouveau_irq_register(dev, 14, nv84_crypt_isr);
nv_wr32(dev, 0x102130, 0xffffffff);
nv_wr32(dev, 0x102140, 0xffffffbf);
@@ -135,29 +157,37 @@ nv84_crypt_init(struct drm_device *dev)
return 0;
}
-void
-nv84_crypt_fini(struct drm_device *dev)
+static void
+nv84_crypt_destroy(struct drm_device *dev, int engine)
{
- nv_wr32(dev, 0x102140, 0x00000000);
+ struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);
+
+ NVOBJ_ENGINE_DEL(dev, CRYPT);
+
nouveau_irq_unregister(dev, 14);
+ kfree(pcrypt);
}
-static void
-nv84_crypt_isr(struct drm_device *dev)
+int
+nv84_crypt_create(struct drm_device *dev)
{
- u32 stat = nv_rd32(dev, 0x102130);
- u32 mthd = nv_rd32(dev, 0x102190);
- u32 data = nv_rd32(dev, 0x102194);
- u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
- int show = nouveau_ratelimit();
+ struct nv84_crypt_engine *pcrypt;
- if (show) {
- NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- stat, mthd, data, inst);
- }
+ pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL);
+ if (!pcrypt)
+ return -ENOMEM;
- nv_wr32(dev, 0x102130, stat);
- nv_wr32(dev, 0x10200c, 0x10);
+ pcrypt->base.destroy = nv84_crypt_destroy;
+ pcrypt->base.init = nv84_crypt_init;
+ pcrypt->base.fini = nv84_crypt_fini;
+ pcrypt->base.context_new = nv84_crypt_context_new;
+ pcrypt->base.context_del = nv84_crypt_context_del;
+ pcrypt->base.object_new = nv84_crypt_object_new;
+ pcrypt->base.tlb_flush = nv84_crypt_tlb_flush;
- nv50_fb_vm_trap(dev, show);
+ nouveau_irq_register(dev, 14, nv84_crypt_isr);
+
+ NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base);
+ NVOBJ_CLASS (dev, 0x74c1, CRYPT);
+ return 0;
}