diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 60 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_vm.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_vm.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv84_crypt.c | 122 |
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 4cea35c57d15..3a047ec1ead3 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 155ebdcbf06f..30b9e89a3a2a 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 31e34ae16dae..6b43cb02dce0 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 f7b806f26f2f..4fb05b6c6985 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 fa81b9017b35..a1a25ea7cc7e 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 2e06b55cfdc1..16ffc4cceebf 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 6c2694490741..1f58b0d62796 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 4918f4e60bab..75b809a51748 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; } |