summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-03-31 15:40:43 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-05-16 10:48:01 +1000
commit6dfdd7a61e8fc25552d9de1cb25272324dfc4c13 (patch)
treed158037ace54303d33323a14bafc8a2ef27a85b5
parent2d7b919c9b0ca3df1da2498bb0cede25ddd97e00 (diff)
downloadop-kernel-dev-6dfdd7a61e8fc25552d9de1cb25272324dfc4c13.zip
op-kernel-dev-6dfdd7a61e8fc25552d9de1cb25272324dfc4c13.tar.gz
drm/nouveau: working towards a common way to represent engines
There's lots of more-or-less independant engines present on NVIDIA GPUs these days, and we generally want to perform the same operations on them. Implementing new ones requires hooking into lots of different places, the aim of this work is to make this simpler and cleaner. NV84:NV98 PCRYPT moved over as a test. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h60
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c81
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vm.h2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_vm.c8
-rw-r--r--drivers/gpu/drm/nouveau/nv84_crypt.c122
8 files changed, 174 insertions, 133 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 4cea35c..3a047ec1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -269,8 +269,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
unsigned long flags;
+ int i;
/* decrement the refcount, and we're done if there's still refs */
if (likely(!atomic_dec_and_test(&chan->users))) {
@@ -305,8 +305,10 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
/* destroy the engine specific contexts */
pfifo->destroy_context(chan);
pgraph->destroy_context(chan);
- if (pcrypt->destroy_context)
- pcrypt->destroy_context(chan);
+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+ if (chan->engctx[i])
+ dev_priv->eng[i]->context_del(chan, i);
+ }
pfifo->reassign(dev, true);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 155ebdc..30b9e89 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -208,6 +208,12 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
pgraph->fifo_access(dev, false);
nouveau_wait_for_idle(dev);
+
+ for (i = NVOBJ_ENGINE_NR - 1; i >= 0; i--) {
+ if (dev_priv->eng[i])
+ dev_priv->eng[i]->fini(dev, i);
+ }
+
pfifo->reassign(dev, false);
pfifo->disable(dev);
pfifo->unload_context(dev);
@@ -299,8 +305,11 @@ nouveau_pci_resume(struct pci_dev *pdev)
engine->mc.init(dev);
engine->timer.init(dev);
engine->fb.init(dev);
+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+ if (dev_priv->eng[i])
+ dev_priv->eng[i]->init(dev, i);
+ }
engine->graph.init(dev);
- engine->crypt.init(dev);
engine->fifo.init(dev);
nouveau_irq_postinstall(dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 31e34ae..6b43cb0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -150,13 +150,9 @@ enum nouveau_flags {
#define NVOBJ_ENGINE_SW 0
#define NVOBJ_ENGINE_GR 1
-#define NVOBJ_ENGINE_PPP 2
-#define NVOBJ_ENGINE_COPY 3
-#define NVOBJ_ENGINE_VP 4
-#define NVOBJ_ENGINE_CRYPT 5
-#define NVOBJ_ENGINE_BSP 6
-#define NVOBJ_ENGINE_DISPLAY 0xcafe0001
-#define NVOBJ_ENGINE_INT 0xdeadbeef
+#define NVOBJ_ENGINE_CRYPT 2
+#define NVOBJ_ENGINE_DISPLAY 15
+#define NVOBJ_ENGINE_NR 16
#define NVOBJ_FLAG_DONT_MAP (1 << 0)
#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
@@ -248,8 +244,8 @@ struct nouveau_channel {
/* PGRAPH context */
/* XXX may be merge 2 pointers as private data ??? */
struct nouveau_gpuobj *ramin_grctx;
- struct nouveau_gpuobj *crypt_ctx;
void *pgraph_ctx;
+ void *engctx[NVOBJ_ENGINE_NR];
/* NV50 VM */
struct nouveau_vm *vm;
@@ -298,6 +294,17 @@ struct nouveau_channel {
} debugfs;
};
+struct nouveau_exec_engine {
+ void (*destroy)(struct drm_device *, int engine);
+ int (*init)(struct drm_device *, int engine);
+ int (*fini)(struct drm_device *, int engine);
+ int (*context_new)(struct nouveau_channel *, int engine);
+ void (*context_del)(struct nouveau_channel *, int engine);
+ int (*object_new)(struct nouveau_channel *, int engine,
+ u32 handle, u16 class);
+ void (*tlb_flush)(struct drm_device *, int engine);
+};
+
struct nouveau_instmem_engine {
void *priv;
@@ -501,17 +508,6 @@ struct nouveau_pm_engine {
int (*temp_get)(struct drm_device *);
};
-struct nouveau_crypt_engine {
- bool registered;
-
- int (*init)(struct drm_device *);
- void (*takedown)(struct drm_device *);
- int (*create_context)(struct nouveau_channel *);
- void (*destroy_context)(struct nouveau_channel *);
- int (*object_new)(struct nouveau_channel *, u32 handle, u16 class);
- void (*tlb_flush)(struct drm_device *dev);
-};
-
struct nouveau_vram_engine {
int (*init)(struct drm_device *);
int (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
@@ -531,7 +527,6 @@ struct nouveau_engine {
struct nouveau_display_engine display;
struct nouveau_gpio_engine gpio;
struct nouveau_pm_engine pm;
- struct nouveau_crypt_engine crypt;
struct nouveau_vram_engine vram;
};
@@ -651,6 +646,7 @@ struct drm_nouveau_private {
u32 ramin_base;
bool ramin_available;
struct drm_mm ramin_heap;
+ struct nouveau_exec_engine *eng[NVOBJ_ENGINE_NR];
struct list_head gpuobj_list;
struct list_head classes;
@@ -881,6 +877,16 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan,
extern void nouveau_channel_idle(struct nouveau_channel *chan);
/* nouveau_object.c */
+#define NVOBJ_ENGINE_ADD(d, e, p) do { \
+ struct drm_nouveau_private *dev_priv = (d)->dev_private; \
+ dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \
+} while (0)
+
+#define NVOBJ_ENGINE_DEL(d, e) do { \
+ struct drm_nouveau_private *dev_priv = (d)->dev_private; \
+ dev_priv->eng[NVOBJ_ENGINE_##e] = NULL; \
+} while (0)
+
#define NVOBJ_CLASS(d, c, e) do { \
int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \
if (ret) \
@@ -1209,12 +1215,7 @@ extern int nvc0_graph_unload_context(struct drm_device *);
extern int nvc0_graph_object_new(struct nouveau_channel *, u32, u16);
/* nv84_crypt.c */
-extern int nv84_crypt_init(struct drm_device *dev);
-extern void nv84_crypt_fini(struct drm_device *dev);
-extern int nv84_crypt_create_context(struct nouveau_channel *);
-extern void nv84_crypt_destroy_context(struct nouveau_channel *);
-extern void nv84_crypt_tlb_flush(struct drm_device *dev);
-extern int nv84_crypt_object_new(struct nouveau_channel *, u32, u16);
+extern int nv84_crypt_create(struct drm_device *);
/* nv04_instmem.c */
extern int nv04_instmem_init(struct drm_device *);
@@ -1582,6 +1583,13 @@ nv_match_device(struct drm_device *dev, unsigned device,
dev->pdev->subsystem_device == sub_device;
}
+static inline void *
+nv_engine(struct drm_device *dev, int engine)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ return (void *)dev_priv->eng[engine];
+}
+
/* returns 1 if device is one of the nv4x using the 0x4497 object class,
* helpful to determine a number of other hardware features
*/
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index f7b806f..4fb05b6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -621,7 +621,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
{
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
struct drm_device *dev = chan->dev;
struct nouveau_gpuobj_class *oc;
int ret;
@@ -649,17 +648,15 @@ found:
}
return pgraph->object_new(chan, handle, class);
- case NVOBJ_ENGINE_CRYPT:
- if (!chan->crypt_ctx) {
- ret = pcrypt->create_context(chan);
- if (ret)
- return ret;
- }
+ }
- return pcrypt->object_new(chan, handle, class);
+ if (!chan->engctx[oc->engine]) {
+ ret = dev_priv->eng[oc->engine]->context_new(chan, oc->engine);
+ if (ret)
+ return ret;
}
- BUG_ON(1);
+ return dev_priv->eng[oc->engine]->object_new(chan, oc->engine, handle, class);
}
static int
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index fa81b90..a1a25ea 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -99,8 +99,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nouveau_mem_detect;
engine->vram.flags_valid = nouveau_mem_flags_valid;
break;
@@ -159,8 +157,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nouveau_mem_detect;
engine->vram.flags_valid = nouveau_mem_flags_valid;
break;
@@ -219,8 +215,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_get = nv04_pm_clock_get;
engine->pm.clock_pre = nv04_pm_clock_pre;
engine->pm.clock_set = nv04_pm_clock_set;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nouveau_mem_detect;
engine->vram.flags_valid = nouveau_mem_flags_valid;
break;
@@ -281,8 +275,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clock_set = nv04_pm_clock_set;
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nouveau_mem_detect;
engine->vram.flags_valid = nouveau_mem_flags_valid;
break;
@@ -345,8 +337,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
engine->pm.temp_get = nv40_temp_get;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nouveau_mem_detect;
engine->vram.flags_valid = nouveau_mem_flags_valid;
break;
@@ -438,25 +428,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.temp_get = nv84_temp_get;
else
engine->pm.temp_get = nv40_temp_get;
- switch (dev_priv->chipset) {
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0xa0:
- engine->crypt.init = nv84_crypt_init;
- engine->crypt.takedown = nv84_crypt_fini;
- engine->crypt.create_context = nv84_crypt_create_context;
- engine->crypt.destroy_context = nv84_crypt_destroy_context;
- engine->crypt.object_new = nv84_crypt_object_new;
- engine->crypt.tlb_flush = nv84_crypt_tlb_flush;
- break;
- default:
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
- break;
- }
engine->vram.init = nv50_vram_init;
engine->vram.get = nv50_vram_new;
engine->vram.put = nv50_vram_del;
@@ -511,8 +482,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->gpio.irq_register = nv50_gpio_irq_register;
engine->gpio.irq_unregister = nv50_gpio_irq_unregister;
engine->gpio.irq_enable = nv50_gpio_irq_enable;
- engine->crypt.init = nouveau_stub_init;
- engine->crypt.takedown = nouveau_stub_takedown;
engine->vram.init = nvc0_vram_init;
engine->vram.get = nvc0_vram_new;
engine->vram.put = nv50_vram_del;
@@ -601,7 +570,7 @@ nouveau_card_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine;
- int ret;
+ int ret, e;
vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
@@ -666,23 +635,37 @@ nouveau_card_init(struct drm_device *dev)
if (ret)
goto out_timer;
+ switch (dev_priv->chipset) {
+ case 0x84:
+ case 0x86:
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ case 0xa0:
+ nv84_crypt_create(dev);
+ break;
+ }
+
if (nouveau_noaccel)
engine->graph.accel_blocked = true;
else {
+ for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
+ if (dev_priv->eng[e]) {
+ ret = dev_priv->eng[e]->init(dev, e);
+ if (ret)
+ goto out_engine;
+ }
+ }
+
/* PGRAPH */
ret = engine->graph.init(dev);
if (ret)
- goto out_fb;
-
- /* PCRYPT */
- ret = engine->crypt.init(dev);
- if (ret)
- goto out_graph;
+ goto out_engine;
/* PFIFO */
ret = engine->fifo.init(dev);
if (ret)
- goto out_crypt;
+ goto out_graph;
}
ret = engine->display.create(dev);
@@ -723,13 +706,17 @@ out_vblank:
out_fifo:
if (!nouveau_noaccel)
engine->fifo.takedown(dev);
-out_crypt:
- if (!nouveau_noaccel)
- engine->crypt.takedown(dev);
out_graph:
if (!nouveau_noaccel)
engine->graph.takedown(dev);
-out_fb:
+out_engine:
+ if (!nouveau_noaccel) {
+ for (e = e - 1; e >= 0; e--) {
+ dev_priv->eng[e]->fini(dev, e);
+ dev_priv->eng[e]->destroy(dev, e);
+ }
+ }
+
engine->fb.takedown(dev);
out_timer:
engine->timer.takedown(dev);
@@ -759,6 +746,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine;
+ int e;
if (!engine->graph.accel_blocked) {
nouveau_fence_fini(dev);
@@ -767,8 +755,13 @@ static void nouveau_card_takedown(struct drm_device *dev)
if (!nouveau_noaccel) {
engine->fifo.takedown(dev);
- engine->crypt.takedown(dev);
engine->graph.takedown(dev);
+ for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
+ if (dev_priv->eng[e]) {
+ dev_priv->eng[e]->fini(dev, e);
+ dev_priv->eng[e]->destroy(dev,e );
+ }
+ }
}
engine->fb.takedown(dev);
engine->timer.takedown(dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h
index 2e06b55..16ffc4cc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h
@@ -54,7 +54,7 @@ struct nouveau_vm {
struct list_head pgd_list;
atomic_t pgraph_refs;
- atomic_t pcrypt_refs;
+ atomic_t engref[16];
struct nouveau_vm_pgt *pgt;
u32 fpde;
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c
index 6c26944..1f58b0d 100644
--- a/drivers/gpu/drm/nouveau/nv50_vm.c
+++ b/drivers/gpu/drm/nouveau/nv50_vm.c
@@ -152,7 +152,7 @@ nv50_vm_flush(struct nouveau_vm *vm)
struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
+ int i;
pinstmem->flush(vm->dev);
@@ -166,8 +166,10 @@ nv50_vm_flush(struct nouveau_vm *vm)
if (atomic_read(&vm->pgraph_refs))
pgraph->tlb_flush(vm->dev);
- if (atomic_read(&vm->pcrypt_refs))
- pcrypt->tlb_flush(vm->dev);
+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+ if (atomic_read(&vm->engref[i]))
+ dev_priv->eng[i]->tlb_flush(vm->dev, i);
+ }
}
void
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
index 4918f4e..75b809a 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;
}
OpenPOWER on IntegriCloud