aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-19 06:06:01 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 00:06:58 -0500
commitbd2e597de8dbd000a3977871f15cb81e2925d63e (patch)
tree4e3fbd24cbc262566cb93dc743cf6b14405eae21
parentb8c157d3a9a13871742c8a8d3d4598c3791ed5f5 (diff)
drm/nv84: add support for the PCRYPT engine
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/Makefile1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h24
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c16
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c62
-rw-r--r--drivers/gpu/drm/nouveau/nv84_crypt.c110
8 files changed, 218 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 23fa82d667d6..a541f5bff75d 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -18,6 +18,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
18 nv04_graph.o nv10_graph.o nv20_graph.o \ 18 nv04_graph.o nv10_graph.o nv20_graph.o \
19 nv40_graph.o nv50_graph.o nvc0_graph.o \ 19 nv40_graph.o nv50_graph.o nvc0_graph.o \
20 nv40_grctx.o nv50_grctx.o \ 20 nv40_grctx.o nv50_grctx.o \
21 nv84_crypt.o \
21 nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ 22 nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
22 nv50_crtc.o nv50_dac.o nv50_sor.o \ 23 nv50_crtc.o nv50_dac.o nv50_sor.o \
23 nv50_cursor.o nv50_display.o nv50_fbcon.o \ 24 nv50_cursor.o nv50_display.o nv50_fbcon.o \
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 76033c509d35..8f2df6beb893 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -112,6 +112,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
112 struct drm_nouveau_private *dev_priv = dev->dev_private; 112 struct drm_nouveau_private *dev_priv = dev->dev_private;
113 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; 113 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
114 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 114 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
115 struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
115 struct nouveau_channel *chan; 116 struct nouveau_channel *chan;
116 unsigned long flags; 117 unsigned long flags;
117 int user, ret; 118 int user, ret;
@@ -214,6 +215,14 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
214 return ret; 215 return ret;
215 } 216 }
216 217
218 if (pcrypt->create_context) {
219 ret = pcrypt->create_context(chan);
220 if (ret) {
221 nouveau_channel_put(&chan);
222 return ret;
223 }
224 }
225
217 /* Construct inital RAMFC for new channel */ 226 /* Construct inital RAMFC for new channel */
218 ret = pfifo->create_context(chan); 227 ret = pfifo->create_context(chan);
219 if (ret) { 228 if (ret) {
@@ -280,6 +289,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
280 struct drm_nouveau_private *dev_priv = dev->dev_private; 289 struct drm_nouveau_private *dev_priv = dev->dev_private;
281 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; 290 struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
282 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; 291 struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
292 struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
283 unsigned long flags; 293 unsigned long flags;
284 int ret; 294 int ret;
285 295
@@ -328,6 +338,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
328 /* destroy the engine specific contexts */ 338 /* destroy the engine specific contexts */
329 pfifo->destroy_context(chan); 339 pfifo->destroy_context(chan);
330 pgraph->destroy_context(chan); 340 pgraph->destroy_context(chan);
341 if (pcrypt->destroy_context)
342 pcrypt->destroy_context(chan);
331 343
332 pfifo->reassign(dev, true); 344 pfifo->reassign(dev, true);
333 345
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index f139aa2cbe5c..6dbb8818c530 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -299,6 +299,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
299 engine->timer.init(dev); 299 engine->timer.init(dev);
300 engine->fb.init(dev); 300 engine->fb.init(dev);
301 engine->graph.init(dev); 301 engine->graph.init(dev);
302 engine->crypt.init(dev);
302 engine->fifo.init(dev); 303 engine->fifo.init(dev);
303 304
304 NV_INFO(dev, "Restoring GPU objects...\n"); 305 NV_INFO(dev, "Restoring GPU objects...\n");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 3fb87995446b..d15bfd427267 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -132,6 +132,11 @@ enum nouveau_flags {
132 132
133#define NVOBJ_ENGINE_SW 0 133#define NVOBJ_ENGINE_SW 0
134#define NVOBJ_ENGINE_GR 1 134#define NVOBJ_ENGINE_GR 1
135#define NVOBJ_ENGINE_PPP 2
136#define NVOBJ_ENGINE_COPY 3
137#define NVOBJ_ENGINE_VP 4
138#define NVOBJ_ENGINE_CRYPT 5
139#define NVOBJ_ENGINE_BSP 6
135#define NVOBJ_ENGINE_DISPLAY 0xcafe0001 140#define NVOBJ_ENGINE_DISPLAY 0xcafe0001
136#define NVOBJ_ENGINE_INT 0xdeadbeef 141#define NVOBJ_ENGINE_INT 0xdeadbeef
137 142
@@ -208,6 +213,7 @@ struct nouveau_channel {
208 /* PGRAPH context */ 213 /* PGRAPH context */
209 /* XXX may be merge 2 pointers as private data ??? */ 214 /* XXX may be merge 2 pointers as private data ??? */
210 struct nouveau_gpuobj *ramin_grctx; 215 struct nouveau_gpuobj *ramin_grctx;
216 struct nouveau_gpuobj *crypt_ctx;
211 void *pgraph_ctx; 217 void *pgraph_ctx;
212 218
213 /* NV50 VM */ 219 /* NV50 VM */
@@ -444,6 +450,16 @@ struct nouveau_pm_engine {
444 int (*temp_get)(struct drm_device *); 450 int (*temp_get)(struct drm_device *);
445}; 451};
446 452
453struct nouveau_crypt_engine {
454 bool registered;
455
456 int (*init)(struct drm_device *);
457 void (*takedown)(struct drm_device *);
458 int (*create_context)(struct nouveau_channel *);
459 void (*destroy_context)(struct nouveau_channel *);
460 void (*tlb_flush)(struct drm_device *dev);
461};
462
447struct nouveau_engine { 463struct nouveau_engine {
448 struct nouveau_instmem_engine instmem; 464 struct nouveau_instmem_engine instmem;
449 struct nouveau_mc_engine mc; 465 struct nouveau_mc_engine mc;
@@ -454,6 +470,7 @@ struct nouveau_engine {
454 struct nouveau_display_engine display; 470 struct nouveau_display_engine display;
455 struct nouveau_gpio_engine gpio; 471 struct nouveau_gpio_engine gpio;
456 struct nouveau_pm_engine pm; 472 struct nouveau_pm_engine pm;
473 struct nouveau_crypt_engine crypt;
457}; 474};
458 475
459struct nouveau_pll_vals { 476struct nouveau_pll_vals {
@@ -1113,6 +1130,13 @@ extern void nvc0_graph_destroy_context(struct nouveau_channel *);
1113extern int nvc0_graph_load_context(struct nouveau_channel *); 1130extern int nvc0_graph_load_context(struct nouveau_channel *);
1114extern int nvc0_graph_unload_context(struct drm_device *); 1131extern int nvc0_graph_unload_context(struct drm_device *);
1115 1132
1133/* nv84_crypt.c */
1134extern int nv84_crypt_init(struct drm_device *dev);
1135extern void nv84_crypt_fini(struct drm_device *dev);
1136extern int nv84_crypt_create_context(struct nouveau_channel *);
1137extern void nv84_crypt_destroy_context(struct nouveau_channel *);
1138extern void nv84_crypt_tlb_flush(struct drm_device *dev);
1139
1116/* nv04_instmem.c */ 1140/* nv04_instmem.c */
1117extern int nv04_instmem_init(struct drm_device *); 1141extern int nv04_instmem_init(struct drm_device *);
1118extern void nv04_instmem_takedown(struct drm_device *); 1142extern void nv04_instmem_takedown(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index f09151d17297..ca9b969f4f9c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -1230,6 +1230,22 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
1230 status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; 1230 status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
1231 } 1231 }
1232 1232
1233 if (status & 0x00004000) {
1234 u32 stat = nv_rd32(dev, 0x102130);
1235 u32 mthd = nv_rd32(dev, 0x102190);
1236 u32 data = nv_rd32(dev, 0x102194);
1237 u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff;
1238
1239 NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1240 stat, mthd, data, inst);
1241 nv_wr32(dev, 0x102130, stat);
1242 nv_wr32(dev, 0x10200c, 0x10);
1243
1244 nv50_fb_vm_trap(dev, nouveau_ratelimit(), "PCRYPT");
1245 status &= ~0x00004000;
1246
1247 }
1248
1233 if (status & NV_PMC_INTR_0_CRTCn_PENDING) { 1249 if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
1234 nouveau_crtc_irq_handler(dev, (status>>24)&3); 1250 nouveau_crtc_irq_handler(dev, (status>>24)&3);
1235 status &= ~NV_PMC_INTR_0_CRTCn_PENDING; 1251 status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 6226beb3613d..ee526534c6f4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -272,6 +272,7 @@ nouveau_gpuobj_init(struct drm_device *dev)
272 NV_DEBUG(dev, "\n"); 272 NV_DEBUG(dev, "\n");
273 273
274 INIT_LIST_HEAD(&dev_priv->gpuobj_list); 274 INIT_LIST_HEAD(&dev_priv->gpuobj_list);
275 INIT_LIST_HEAD(&dev_priv->classes);
275 spin_lock_init(&dev_priv->ramin_lock); 276 spin_lock_init(&dev_priv->ramin_lock);
276 dev_priv->ramin_base = ~0; 277 dev_priv->ramin_base = ~0;
277 278
@@ -686,7 +687,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
686 NV_DEBUG(dev, "ch%d\n", chan->id); 687 NV_DEBUG(dev, "ch%d\n", chan->id);
687 688
688 /* Base amount for object storage (4KiB enough?) */ 689 /* Base amount for object storage (4KiB enough?) */
689 size = 0x1000; 690 size = 0x2000;
690 base = 0; 691 base = 0;
691 692
692 /* PGRAPH context */ 693 /* PGRAPH context */
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index be28754ffd50..f13134aa8c4f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -98,6 +98,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
98 engine->pm.clock_get = nv04_pm_clock_get; 98 engine->pm.clock_get = nv04_pm_clock_get;
99 engine->pm.clock_pre = nv04_pm_clock_pre; 99 engine->pm.clock_pre = nv04_pm_clock_pre;
100 engine->pm.clock_set = nv04_pm_clock_set; 100 engine->pm.clock_set = nv04_pm_clock_set;
101 engine->crypt.init = nouveau_stub_init;
102 engine->crypt.takedown = nouveau_stub_takedown;
101 break; 103 break;
102 case 0x10: 104 case 0x10:
103 engine->instmem.init = nv04_instmem_init; 105 engine->instmem.init = nv04_instmem_init;
@@ -151,6 +153,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
151 engine->pm.clock_get = nv04_pm_clock_get; 153 engine->pm.clock_get = nv04_pm_clock_get;
152 engine->pm.clock_pre = nv04_pm_clock_pre; 154 engine->pm.clock_pre = nv04_pm_clock_pre;
153 engine->pm.clock_set = nv04_pm_clock_set; 155 engine->pm.clock_set = nv04_pm_clock_set;
156 engine->crypt.init = nouveau_stub_init;
157 engine->crypt.takedown = nouveau_stub_takedown;
154 break; 158 break;
155 case 0x20: 159 case 0x20:
156 engine->instmem.init = nv04_instmem_init; 160 engine->instmem.init = nv04_instmem_init;
@@ -204,6 +208,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
204 engine->pm.clock_get = nv04_pm_clock_get; 208 engine->pm.clock_get = nv04_pm_clock_get;
205 engine->pm.clock_pre = nv04_pm_clock_pre; 209 engine->pm.clock_pre = nv04_pm_clock_pre;
206 engine->pm.clock_set = nv04_pm_clock_set; 210 engine->pm.clock_set = nv04_pm_clock_set;
211 engine->crypt.init = nouveau_stub_init;
212 engine->crypt.takedown = nouveau_stub_takedown;
207 break; 213 break;
208 case 0x30: 214 case 0x30:
209 engine->instmem.init = nv04_instmem_init; 215 engine->instmem.init = nv04_instmem_init;
@@ -259,6 +265,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
259 engine->pm.clock_set = nv04_pm_clock_set; 265 engine->pm.clock_set = nv04_pm_clock_set;
260 engine->pm.voltage_get = nouveau_voltage_gpio_get; 266 engine->pm.voltage_get = nouveau_voltage_gpio_get;
261 engine->pm.voltage_set = nouveau_voltage_gpio_set; 267 engine->pm.voltage_set = nouveau_voltage_gpio_set;
268 engine->crypt.init = nouveau_stub_init;
269 engine->crypt.takedown = nouveau_stub_takedown;
262 break; 270 break;
263 case 0x40: 271 case 0x40:
264 case 0x60: 272 case 0x60:
@@ -316,6 +324,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
316 engine->pm.voltage_get = nouveau_voltage_gpio_get; 324 engine->pm.voltage_get = nouveau_voltage_gpio_get;
317 engine->pm.voltage_set = nouveau_voltage_gpio_set; 325 engine->pm.voltage_set = nouveau_voltage_gpio_set;
318 engine->pm.temp_get = nv40_temp_get; 326 engine->pm.temp_get = nv40_temp_get;
327 engine->crypt.init = nouveau_stub_init;
328 engine->crypt.takedown = nouveau_stub_takedown;
319 break; 329 break;
320 case 0x50: 330 case 0x50:
321 case 0x80: /* gotta love NVIDIA's consistency.. */ 331 case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -380,19 +390,23 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
380 engine->gpio.set = nv50_gpio_set; 390 engine->gpio.set = nv50_gpio_set;
381 engine->gpio.irq_enable = nv50_gpio_irq_enable; 391 engine->gpio.irq_enable = nv50_gpio_irq_enable;
382 switch (dev_priv->chipset) { 392 switch (dev_priv->chipset) {
383 case 0xa3: 393 case 0x84:
384 case 0xa5: 394 case 0x86:
385 case 0xa8: 395 case 0x92:
386 case 0xaf: 396 case 0x94:
387 engine->pm.clock_get = nva3_pm_clock_get; 397 case 0x96:
388 engine->pm.clock_pre = nva3_pm_clock_pre; 398 case 0x98:
389 engine->pm.clock_set = nva3_pm_clock_set; 399 case 0xa0:
390 break; 400 case 0x50:
391 default:
392 engine->pm.clock_get = nv50_pm_clock_get; 401 engine->pm.clock_get = nv50_pm_clock_get;
393 engine->pm.clock_pre = nv50_pm_clock_pre; 402 engine->pm.clock_pre = nv50_pm_clock_pre;
394 engine->pm.clock_set = nv50_pm_clock_set; 403 engine->pm.clock_set = nv50_pm_clock_set;
395 break; 404 break;
405 default:
406 engine->pm.clock_get = nva3_pm_clock_get;
407 engine->pm.clock_pre = nva3_pm_clock_pre;
408 engine->pm.clock_set = nva3_pm_clock_set;
409 break;
396 } 410 }
397 engine->pm.voltage_get = nouveau_voltage_gpio_get; 411 engine->pm.voltage_get = nouveau_voltage_gpio_get;
398 engine->pm.voltage_set = nouveau_voltage_gpio_set; 412 engine->pm.voltage_set = nouveau_voltage_gpio_set;
@@ -400,6 +414,23 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
400 engine->pm.temp_get = nv84_temp_get; 414 engine->pm.temp_get = nv84_temp_get;
401 else 415 else
402 engine->pm.temp_get = nv40_temp_get; 416 engine->pm.temp_get = nv40_temp_get;
417 switch (dev_priv->chipset) {
418 case 0x84:
419 case 0x86:
420 case 0x92:
421 case 0x94:
422 case 0x96:
423 case 0xa0:
424 engine->crypt.init = nv84_crypt_init;
425 engine->crypt.takedown = nv84_crypt_fini;
426 engine->crypt.create_context = nv84_crypt_create_context;
427 engine->crypt.destroy_context = nv84_crypt_destroy_context;
428 break;
429 default:
430 engine->crypt.init = nouveau_stub_init;
431 engine->crypt.takedown = nouveau_stub_takedown;
432 break;
433 }
403 break; 434 break;
404 case 0xC0: 435 case 0xC0:
405 engine->instmem.init = nvc0_instmem_init; 436 engine->instmem.init = nvc0_instmem_init;
@@ -447,6 +478,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
447 engine->gpio.get = nv50_gpio_get; 478 engine->gpio.get = nv50_gpio_get;
448 engine->gpio.set = nv50_gpio_set; 479 engine->gpio.set = nv50_gpio_set;
449 engine->gpio.irq_enable = nv50_gpio_irq_enable; 480 engine->gpio.irq_enable = nv50_gpio_irq_enable;
481 engine->crypt.init = nouveau_stub_init;
482 engine->crypt.takedown = nouveau_stub_takedown;
450 break; 483 break;
451 default: 484 default:
452 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 485 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -619,10 +652,15 @@ nouveau_card_init(struct drm_device *dev)
619 if (ret) 652 if (ret)
620 goto out_fb; 653 goto out_fb;
621 654
655 /* PCRYPT */
656 ret = engine->crypt.init(dev);
657 if (ret)
658 goto out_graph;
659
622 /* PFIFO */ 660 /* PFIFO */
623 ret = engine->fifo.init(dev); 661 ret = engine->fifo.init(dev);
624 if (ret) 662 if (ret)
625 goto out_graph; 663 goto out_crypt;
626 } 664 }
627 665
628 ret = engine->display.create(dev); 666 ret = engine->display.create(dev);
@@ -669,6 +707,9 @@ out_display:
669out_fifo: 707out_fifo:
670 if (!nouveau_noaccel) 708 if (!nouveau_noaccel)
671 engine->fifo.takedown(dev); 709 engine->fifo.takedown(dev);
710out_crypt:
711 if (!nouveau_noaccel)
712 engine->crypt.takedown(dev);
672out_graph: 713out_graph:
673 if (!nouveau_noaccel) 714 if (!nouveau_noaccel)
674 engine->graph.takedown(dev); 715 engine->graph.takedown(dev);
@@ -712,6 +753,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
712 753
713 if (!nouveau_noaccel) { 754 if (!nouveau_noaccel) {
714 engine->fifo.takedown(dev); 755 engine->fifo.takedown(dev);
756 engine->crypt.takedown(dev);
715 engine->graph.takedown(dev); 757 engine->graph.takedown(dev);
716 } 758 }
717 engine->fb.takedown(dev); 759 engine->fb.takedown(dev);
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
new file mode 100644
index 000000000000..63bd6bb41e38
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright 2010 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "drmP.h"
26#include "nouveau_drv.h"
27
28int
29nv84_crypt_create_context(struct nouveau_channel *chan)
30{
31 struct drm_device *dev = chan->dev;
32 struct drm_nouveau_private *dev_priv = dev->dev_private;
33 struct nouveau_gpuobj *ramin = chan->ramin;
34 int ret;
35
36 NV_DEBUG(dev, "ch%d\n", chan->id);
37
38 ret = nouveau_gpuobj_new(dev, chan, 256, 0x1000,
39 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
40 &chan->crypt_ctx);
41 if (ret)
42 return ret;
43
44 nv_wo32(ramin, 0xa0, 0x00190000);
45 nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff);
46 nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst);
47 nv_wo32(ramin, 0xac, 0);
48 nv_wo32(ramin, 0xb0, 0);
49 nv_wo32(ramin, 0xb4, 0);
50
51 dev_priv->engine.instmem.flush(dev);
52 return 0;
53}
54
55void
56nv84_crypt_destroy_context(struct nouveau_channel *chan)
57{
58 struct drm_device *dev = chan->dev;
59 u32 inst;
60
61 if (!chan->ramin)
62 return;
63
64 inst = (chan->ramin->vinst >> 12);
65 inst |= 0x80000000;
66
67 /* mark context as invalid if still on the hardware, not
68 * doing this causes issues the next time PCRYPT is used,
69 * unsurprisingly :)
70 */
71 nv_wr32(dev, 0x10200c, 0x00000000);
72 if (nv_rd32(dev, 0x102188) == inst)
73 nv_mask(dev, 0x102188, 0x80000000, 0x00000000);
74 if (nv_rd32(dev, 0x10218c) == inst)
75 nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
76 nv_wr32(dev, 0x10200c, 0x00000010);
77
78 nouveau_gpuobj_ref(NULL, &chan->crypt_ctx);
79}
80
81void
82nv84_crypt_tlb_flush(struct drm_device *dev)
83{
84 nv50_vm_flush(dev, 0x0a);
85}
86
87int
88nv84_crypt_init(struct drm_device *dev)
89{
90 struct drm_nouveau_private *dev_priv = dev->dev_private;
91 struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
92
93 if (!pcrypt->registered) {
94 NVOBJ_CLASS(dev, 0x74c1, CRYPT);
95 pcrypt->registered = true;
96 }
97
98 nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
99 nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
100 nv_wr32(dev, 0x102130, 0xffffffff);
101 nv_wr32(dev, 0x102140, 0xffffffbf);
102 nv_wr32(dev, 0x10200c, 0x00000010);
103 return 0;
104}
105
106void
107nv84_crypt_fini(struct drm_device *dev)
108{
109 nv_wr32(dev, 0x102140, 0x00000000);
110}