aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv84_crypt.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-03-31 01:40:43 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-05-15 20:48:01 -0400
commit6dfdd7a61e8fc25552d9de1cb25272324dfc4c13 (patch)
treed158037ace54303d33323a14bafc8a2ef27a85b5 /drivers/gpu/drm/nouveau/nv84_crypt.c
parent2d7b919c9b0ca3df1da2498bb0cede25ddd97e00 (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_crypt.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv84_crypt.c122
1 files changed, 76 insertions, 46 deletions
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 @@
28#include "nouveau_vm.h" 28#include "nouveau_vm.h"
29#include "nouveau_ramht.h" 29#include "nouveau_ramht.h"
30 30
31static void nv84_crypt_isr(struct drm_device *); 31struct nv84_crypt_engine {
32 struct nouveau_exec_engine base;
33};
32 34
33int 35static int
34nv84_crypt_create_context(struct nouveau_channel *chan) 36nv84_crypt_context_new(struct nouveau_channel *chan, int engine)
35{ 37{
36 struct drm_device *dev = chan->dev; 38 struct drm_device *dev = chan->dev;
37 struct drm_nouveau_private *dev_priv = dev->dev_private; 39 struct drm_nouveau_private *dev_priv = dev->dev_private;
38 struct nouveau_gpuobj *ramin = chan->ramin; 40 struct nouveau_gpuobj *ramin = chan->ramin;
41 struct nouveau_gpuobj *ctx;
39 int ret; 42 int ret;
40 43
41 NV_DEBUG(dev, "ch%d\n", chan->id); 44 NV_DEBUG(dev, "ch%d\n", chan->id);
42 45
43 ret = nouveau_gpuobj_new(dev, chan, 256, 0, 46 ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
44 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, 47 NVOBJ_FLAG_ZERO_FREE, &ctx);
45 &chan->crypt_ctx);
46 if (ret) 48 if (ret)
47 return ret; 49 return ret;
48 50
49 nv_wo32(ramin, 0xa0, 0x00190000); 51 nv_wo32(ramin, 0xa0, 0x00190000);
50 nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff); 52 nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
51 nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst); 53 nv_wo32(ramin, 0xa8, ctx->vinst);
52 nv_wo32(ramin, 0xac, 0); 54 nv_wo32(ramin, 0xac, 0);
53 nv_wo32(ramin, 0xb0, 0); 55 nv_wo32(ramin, 0xb0, 0);
54 nv_wo32(ramin, 0xb4, 0); 56 nv_wo32(ramin, 0xb4, 0);
55
56 dev_priv->engine.instmem.flush(dev); 57 dev_priv->engine.instmem.flush(dev);
57 atomic_inc(&chan->vm->pcrypt_refs); 58
59 atomic_inc(&chan->vm->engref[engine]);
60 chan->engctx[engine] = ctx;
58 return 0; 61 return 0;
59} 62}
60 63
61void 64static void
62nv84_crypt_destroy_context(struct nouveau_channel *chan) 65nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
63{ 66{
67 struct nouveau_gpuobj *ctx = chan->engctx[engine];
64 struct drm_device *dev = chan->dev; 68 struct drm_device *dev = chan->dev;
65 u32 inst; 69 u32 inst;
66 70
67 if (!chan->crypt_ctx)
68 return;
69
70 inst = (chan->ramin->vinst >> 12); 71 inst = (chan->ramin->vinst >> 12);
71 inst |= 0x80000000; 72 inst |= 0x80000000;
72 73
@@ -81,12 +82,15 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan)
81 nv_mask(dev, 0x10218c, 0x80000000, 0x00000000); 82 nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
82 nv_wr32(dev, 0x10200c, 0x00000010); 83 nv_wr32(dev, 0x10200c, 0x00000010);
83 84
84 nouveau_gpuobj_ref(NULL, &chan->crypt_ctx); 85 nouveau_gpuobj_ref(NULL, &ctx);
85 atomic_dec(&chan->vm->pcrypt_refs); 86
87 atomic_dec(&chan->vm->engref[engine]);
88 chan->engctx[engine] = NULL;
86} 89}
87 90
88int 91static int
89nv84_crypt_object_new(struct nouveau_channel *chan, u32 handle, u16 class) 92nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
93 u32 handle, u16 class)
90{ 94{
91 struct drm_device *dev = chan->dev; 95 struct drm_device *dev = chan->dev;
92 struct drm_nouveau_private *dev_priv = dev->dev_private; 96 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)
107 return ret; 111 return ret;
108} 112}
109 113
110void 114static void
111nv84_crypt_tlb_flush(struct drm_device *dev) 115nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
112{ 116{
113 nv50_vm_flush_engine(dev, 0x0a); 117 nv50_vm_flush_engine(dev, 0x0a);
114} 118}
115 119
116int 120static void
117nv84_crypt_init(struct drm_device *dev) 121nv84_crypt_isr(struct drm_device *dev)
118{ 122{
119 struct drm_nouveau_private *dev_priv = dev->dev_private; 123 u32 stat = nv_rd32(dev, 0x102130);
120 struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; 124 u32 mthd = nv_rd32(dev, 0x102190);
125 u32 data = nv_rd32(dev, 0x102194);
126 u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
127 int show = nouveau_ratelimit();
121 128
122 if (!pcrypt->registered) { 129 if (show) {
123 NVOBJ_CLASS(dev, 0x74c1, CRYPT); 130 NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
124 pcrypt->registered = true; 131 stat, mthd, data, inst);
125 } 132 }
126 133
134 nv_wr32(dev, 0x102130, stat);
135 nv_wr32(dev, 0x10200c, 0x10);
136
137 nv50_fb_vm_trap(dev, show);
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{
127 nv_mask(dev, 0x000200, 0x00004000, 0x00000000); 150 nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
128 nv_mask(dev, 0x000200, 0x00004000, 0x00004000); 151 nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
129 152
130 nouveau_irq_register(dev, 14, nv84_crypt_isr);
131 nv_wr32(dev, 0x102130, 0xffffffff); 153 nv_wr32(dev, 0x102130, 0xffffffff);
132 nv_wr32(dev, 0x102140, 0xffffffbf); 154 nv_wr32(dev, 0x102140, 0xffffffbf);
133 155
@@ -135,29 +157,37 @@ nv84_crypt_init(struct drm_device *dev)
135 return 0; 157 return 0;
136} 158}
137 159
138void 160static void
139nv84_crypt_fini(struct drm_device *dev) 161nv84_crypt_destroy(struct drm_device *dev, int engine)
140{ 162{
141 nv_wr32(dev, 0x102140, 0x00000000); 163 struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);
164
165 NVOBJ_ENGINE_DEL(dev, CRYPT);
166
142 nouveau_irq_unregister(dev, 14); 167 nouveau_irq_unregister(dev, 14);
168 kfree(pcrypt);
143} 169}
144 170
145static void 171int
146nv84_crypt_isr(struct drm_device *dev) 172nv84_crypt_create(struct drm_device *dev)
147{ 173{
148 u32 stat = nv_rd32(dev, 0x102130); 174 struct nv84_crypt_engine *pcrypt;
149 u32 mthd = nv_rd32(dev, 0x102190);
150 u32 data = nv_rd32(dev, 0x102194);
151 u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
152 int show = nouveau_ratelimit();
153 175
154 if (show) { 176 pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL);
155 NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", 177 if (!pcrypt)
156 stat, mthd, data, inst); 178 return -ENOMEM;
157 }
158 179
159 nv_wr32(dev, 0x102130, stat); 180 pcrypt->base.destroy = nv84_crypt_destroy;
160 nv_wr32(dev, 0x10200c, 0x10); 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;
161 187
162 nv50_fb_vm_trap(dev, show); 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;
163} 193}