diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-19 06:06:01 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:06:58 -0500 |
commit | bd2e597de8dbd000a3977871f15cb81e2925d63e (patch) | |
tree | 4e3fbd24cbc262566cb93dc743cf6b14405eae21 | |
parent | b8c157d3a9a13871742c8a8d3d4598c3791ed5f5 (diff) |
drm/nv84: add support for the PCRYPT engine
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv84_crypt.c | 110 |
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 | ||
453 | struct 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 | |||
447 | struct nouveau_engine { | 463 | struct 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 | ||
459 | struct nouveau_pll_vals { | 476 | struct nouveau_pll_vals { |
@@ -1113,6 +1130,13 @@ extern void nvc0_graph_destroy_context(struct nouveau_channel *); | |||
1113 | extern int nvc0_graph_load_context(struct nouveau_channel *); | 1130 | extern int nvc0_graph_load_context(struct nouveau_channel *); |
1114 | extern int nvc0_graph_unload_context(struct drm_device *); | 1131 | extern int nvc0_graph_unload_context(struct drm_device *); |
1115 | 1132 | ||
1133 | /* nv84_crypt.c */ | ||
1134 | extern int nv84_crypt_init(struct drm_device *dev); | ||
1135 | extern void nv84_crypt_fini(struct drm_device *dev); | ||
1136 | extern int nv84_crypt_create_context(struct nouveau_channel *); | ||
1137 | extern void nv84_crypt_destroy_context(struct nouveau_channel *); | ||
1138 | extern void nv84_crypt_tlb_flush(struct drm_device *dev); | ||
1139 | |||
1116 | /* nv04_instmem.c */ | 1140 | /* nv04_instmem.c */ |
1117 | extern int nv04_instmem_init(struct drm_device *); | 1141 | extern int nv04_instmem_init(struct drm_device *); |
1118 | extern void nv04_instmem_takedown(struct drm_device *); | 1142 | extern 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: | |||
669 | out_fifo: | 707 | out_fifo: |
670 | if (!nouveau_noaccel) | 708 | if (!nouveau_noaccel) |
671 | engine->fifo.takedown(dev); | 709 | engine->fifo.takedown(dev); |
710 | out_crypt: | ||
711 | if (!nouveau_noaccel) | ||
712 | engine->crypt.takedown(dev); | ||
672 | out_graph: | 713 | out_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 | |||
28 | int | ||
29 | nv84_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 | |||
55 | void | ||
56 | nv84_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 | |||
81 | void | ||
82 | nv84_crypt_tlb_flush(struct drm_device *dev) | ||
83 | { | ||
84 | nv50_vm_flush(dev, 0x0a); | ||
85 | } | ||
86 | |||
87 | int | ||
88 | nv84_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 | |||
106 | void | ||
107 | nv84_crypt_fini(struct drm_device *dev) | ||
108 | { | ||
109 | nv_wr32(dev, 0x102140, 0x00000000); | ||
110 | } | ||