aboutsummaryrefslogtreecommitdiffstats
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.c135
1 files changed, 94 insertions, 41 deletions
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
index fabc7fd30b1d..75b809a51748 100644
--- a/drivers/gpu/drm/nouveau/nv84_crypt.c
+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
@@ -26,46 +26,48 @@
26#include "nouveau_drv.h" 26#include "nouveau_drv.h"
27#include "nouveau_util.h" 27#include "nouveau_util.h"
28#include "nouveau_vm.h" 28#include "nouveau_vm.h"
29#include "nouveau_ramht.h"
29 30
30static void nv84_crypt_isr(struct drm_device *); 31struct nv84_crypt_engine {
32 struct nouveau_exec_engine base;
33};
31 34
32int 35static int
33nv84_crypt_create_context(struct nouveau_channel *chan) 36nv84_crypt_context_new(struct nouveau_channel *chan, int engine)
34{ 37{
35 struct drm_device *dev = chan->dev; 38 struct drm_device *dev = chan->dev;
36 struct drm_nouveau_private *dev_priv = dev->dev_private; 39 struct drm_nouveau_private *dev_priv = dev->dev_private;
37 struct nouveau_gpuobj *ramin = chan->ramin; 40 struct nouveau_gpuobj *ramin = chan->ramin;
41 struct nouveau_gpuobj *ctx;
38 int ret; 42 int ret;
39 43
40 NV_DEBUG(dev, "ch%d\n", chan->id); 44 NV_DEBUG(dev, "ch%d\n", chan->id);
41 45
42 ret = nouveau_gpuobj_new(dev, chan, 256, 0, 46 ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
43 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, 47 NVOBJ_FLAG_ZERO_FREE, &ctx);
44 &chan->crypt_ctx);
45 if (ret) 48 if (ret)
46 return ret; 49 return ret;
47 50
48 nv_wo32(ramin, 0xa0, 0x00190000); 51 nv_wo32(ramin, 0xa0, 0x00190000);
49 nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff); 52 nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
50 nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst); 53 nv_wo32(ramin, 0xa8, ctx->vinst);
51 nv_wo32(ramin, 0xac, 0); 54 nv_wo32(ramin, 0xac, 0);
52 nv_wo32(ramin, 0xb0, 0); 55 nv_wo32(ramin, 0xb0, 0);
53 nv_wo32(ramin, 0xb4, 0); 56 nv_wo32(ramin, 0xb4, 0);
54
55 dev_priv->engine.instmem.flush(dev); 57 dev_priv->engine.instmem.flush(dev);
56 atomic_inc(&chan->vm->pcrypt_refs); 58
59 atomic_inc(&chan->vm->engref[engine]);
60 chan->engctx[engine] = ctx;
57 return 0; 61 return 0;
58} 62}
59 63
60void 64static void
61nv84_crypt_destroy_context(struct nouveau_channel *chan) 65nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
62{ 66{
67 struct nouveau_gpuobj *ctx = chan->engctx[engine];
63 struct drm_device *dev = chan->dev; 68 struct drm_device *dev = chan->dev;
64 u32 inst; 69 u32 inst;
65 70
66 if (!chan->crypt_ctx)
67 return;
68
69 inst = (chan->ramin->vinst >> 12); 71 inst = (chan->ramin->vinst >> 12);
70 inst |= 0x80000000; 72 inst |= 0x80000000;
71 73
@@ -80,43 +82,39 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan)
80 nv_mask(dev, 0x10218c, 0x80000000, 0x00000000); 82 nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
81 nv_wr32(dev, 0x10200c, 0x00000010); 83 nv_wr32(dev, 0x10200c, 0x00000010);
82 84
83 nouveau_gpuobj_ref(NULL, &chan->crypt_ctx); 85 nouveau_gpuobj_ref(NULL, &ctx);
84 atomic_dec(&chan->vm->pcrypt_refs);
85}
86 86
87void 87 atomic_dec(&chan->vm->engref[engine]);
88nv84_crypt_tlb_flush(struct drm_device *dev) 88 chan->engctx[engine] = NULL;
89{
90 nv50_vm_flush_engine(dev, 0x0a);
91} 89}
92 90
93int 91static int
94nv84_crypt_init(struct drm_device *dev) 92nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
93 u32 handle, u16 class)
95{ 94{
95 struct drm_device *dev = chan->dev;
96 struct drm_nouveau_private *dev_priv = dev->dev_private; 96 struct drm_nouveau_private *dev_priv = dev->dev_private;
97 struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; 97 struct nouveau_gpuobj *obj = NULL;
98 98 int ret;
99 if (!pcrypt->registered) {
100 NVOBJ_CLASS(dev, 0x74c1, CRYPT);
101 pcrypt->registered = true;
102 }
103 99
104 nv_mask(dev, 0x000200, 0x00004000, 0x00000000); 100 ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
105 nv_mask(dev, 0x000200, 0x00004000, 0x00004000); 101 if (ret)
102 return ret;
103 obj->engine = 5;
104 obj->class = class;
106 105
107 nouveau_irq_register(dev, 14, nv84_crypt_isr); 106 nv_wo32(obj, 0x00, class);
108 nv_wr32(dev, 0x102130, 0xffffffff); 107 dev_priv->engine.instmem.flush(dev);
109 nv_wr32(dev, 0x102140, 0xffffffbf);
110 108
111 nv_wr32(dev, 0x10200c, 0x00000010); 109 ret = nouveau_ramht_insert(chan, handle, obj);
112 return 0; 110 nouveau_gpuobj_ref(NULL, &obj);
111 return ret;
113} 112}
114 113
115void 114static void
116nv84_crypt_fini(struct drm_device *dev) 115nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
117{ 116{
118 nv_wr32(dev, 0x102140, 0x00000000); 117 nv50_vm_flush_engine(dev, 0x0a);
119 nouveau_irq_unregister(dev, 14);
120} 118}
121 119
122static void 120static void
@@ -138,3 +136,58 @@ nv84_crypt_isr(struct drm_device *dev)
138 136
139 nv50_fb_vm_trap(dev, show); 137 nv50_fb_vm_trap(dev, show);
140} 138}
139
140static int
141nv84_crypt_fini(struct drm_device *dev, int engine)
142{
143 nv_wr32(dev, 0x102140, 0x00000000);
144 return 0;
145}
146
147static int
148nv84_crypt_init(struct drm_device *dev, int engine)
149{
150 nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
151 nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
152
153 nv_wr32(dev, 0x102130, 0xffffffff);
154 nv_wr32(dev, 0x102140, 0xffffffbf);
155
156 nv_wr32(dev, 0x10200c, 0x00000010);
157 return 0;
158}
159
160static void
161nv84_crypt_destroy(struct drm_device *dev, int engine)
162{
163 struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);
164
165 NVOBJ_ENGINE_DEL(dev, CRYPT);
166
167 nouveau_irq_unregister(dev, 14);
168 kfree(pcrypt);
169}
170
171int
172nv84_crypt_create(struct drm_device *dev)
173{
174 struct nv84_crypt_engine *pcrypt;
175
176 pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL);
177 if (!pcrypt)
178 return -ENOMEM;
179
180 pcrypt->base.destroy = nv84_crypt_destroy;
181 pcrypt->base.init = nv84_crypt_init;
182 pcrypt->base.fini = nv84_crypt_fini;
183 pcrypt->base.context_new = nv84_crypt_context_new;
184 pcrypt->base.context_del = nv84_crypt_context_del;
185 pcrypt->base.object_new = nv84_crypt_object_new;
186 pcrypt->base.tlb_flush = nv84_crypt_tlb_flush;
187
188 nouveau_irq_register(dev, 14, nv84_crypt_isr);
189
190 NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base);
191 NVOBJ_CLASS (dev, 0x74c1, CRYPT);
192 return 0;
193}