|
@@ -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;
|
|
|
}
|