diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_crypt.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv84_crypt.c | 135 |
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 | ||
30 | static void nv84_crypt_isr(struct drm_device *); | 31 | struct nv84_crypt_engine { |
32 | struct nouveau_exec_engine base; | ||
33 | }; | ||
31 | 34 | ||
32 | int | 35 | static int |
33 | nv84_crypt_create_context(struct nouveau_channel *chan) | 36 | nv84_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 | ||
60 | void | 64 | static void |
61 | nv84_crypt_destroy_context(struct nouveau_channel *chan) | 65 | nv84_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 | ||
87 | void | 87 | atomic_dec(&chan->vm->engref[engine]); |
88 | nv84_crypt_tlb_flush(struct drm_device *dev) | 88 | chan->engctx[engine] = NULL; |
89 | { | ||
90 | nv50_vm_flush_engine(dev, 0x0a); | ||
91 | } | 89 | } |
92 | 90 | ||
93 | int | 91 | static int |
94 | nv84_crypt_init(struct drm_device *dev) | 92 | nv84_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 | ||
115 | void | 114 | static void |
116 | nv84_crypt_fini(struct drm_device *dev) | 115 | nv84_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 | ||
122 | static void | 120 | static 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 | |||
140 | static int | ||
141 | nv84_crypt_fini(struct drm_device *dev, int engine) | ||
142 | { | ||
143 | nv_wr32(dev, 0x102140, 0x00000000); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int | ||
148 | nv84_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 | |||
160 | static void | ||
161 | nv84_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 | |||
171 | int | ||
172 | nv84_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 | } | ||