diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-11-15 20:50:09 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:11:59 -0500 |
commit | 7f4a195fcbd8b16f25f1de7f1419414d7505daa5 (patch) | |
tree | d54405e52a42c41f6e88ff3ae3685afe2aa57f34 | |
parent | 6d6c5a157af45a5bd50ab913b07d826811a9ea0a (diff) |
drm/nouveau: tidy up and extend dma object creation interfaces
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_channel.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_notifier.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 235 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_reg.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_sgdma.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 9 |
8 files changed, 184 insertions, 160 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 11b2370e16da..0f33132fba3b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -39,22 +39,22 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | |||
39 | 39 | ||
40 | if (dev_priv->card_type >= NV_50) { | 40 | if (dev_priv->card_type >= NV_50) { |
41 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, | 41 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, |
42 | dev_priv->vm_end, NV_DMA_ACCESS_RO, | 42 | dev_priv->vm_end, NV_MEM_ACCESS_RO, |
43 | NV_DMA_TARGET_AGP, &pushbuf); | 43 | NV_MEM_TARGET_VM, &pushbuf); |
44 | chan->pushbuf_base = pb->bo.offset; | 44 | chan->pushbuf_base = pb->bo.offset; |
45 | } else | 45 | } else |
46 | if (pb->bo.mem.mem_type == TTM_PL_TT) { | 46 | if (pb->bo.mem.mem_type == TTM_PL_TT) { |
47 | ret = nouveau_gpuobj_gart_dma_new(chan, 0, | 47 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, |
48 | dev_priv->gart_info.aper_size, | 48 | dev_priv->gart_info.aper_size, |
49 | NV_DMA_ACCESS_RO, &pushbuf, | 49 | NV_MEM_ACCESS_RO, |
50 | NULL); | 50 | NV_MEM_TARGET_GART, &pushbuf); |
51 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; | 51 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; |
52 | } else | 52 | } else |
53 | if (dev_priv->card_type != NV_04) { | 53 | if (dev_priv->card_type != NV_04) { |
54 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, | 54 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, |
55 | dev_priv->fb_available_size, | 55 | dev_priv->fb_available_size, |
56 | NV_DMA_ACCESS_RO, | 56 | NV_MEM_ACCESS_RO, |
57 | NV_DMA_TARGET_VIDMEM, &pushbuf); | 57 | NV_MEM_TARGET_VRAM, &pushbuf); |
58 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; | 58 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; |
59 | } else { | 59 | } else { |
60 | /* NV04 cmdbuf hack, from original ddx.. not sure of it's | 60 | /* NV04 cmdbuf hack, from original ddx.. not sure of it's |
@@ -62,11 +62,10 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | |||
62 | * VRAM. | 62 | * VRAM. |
63 | */ | 63 | */ |
64 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 64 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
65 | pci_resource_start(dev->pdev, | 65 | pci_resource_start(dev->pdev, 1), |
66 | 1), | ||
67 | dev_priv->fb_available_size, | 66 | dev_priv->fb_available_size, |
68 | NV_DMA_ACCESS_RO, | 67 | NV_MEM_ACCESS_RO, |
69 | NV_DMA_TARGET_PCI, &pushbuf); | 68 | NV_MEM_TARGET_PCI, &pushbuf); |
70 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; | 69 | chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; |
71 | } | 70 | } |
72 | 71 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d76d2c09049d..a52b1da32031 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -886,12 +886,14 @@ extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst, | |||
886 | extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, | 886 | extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, |
887 | uint64_t offset, uint64_t size, int access, | 887 | uint64_t offset, uint64_t size, int access, |
888 | int target, struct nouveau_gpuobj **); | 888 | int target, struct nouveau_gpuobj **); |
889 | extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, | ||
890 | uint64_t offset, uint64_t size, | ||
891 | int access, struct nouveau_gpuobj **, | ||
892 | uint32_t *o_ret); | ||
893 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, | 889 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, |
894 | struct nouveau_gpuobj **); | 890 | struct nouveau_gpuobj **); |
891 | extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base, | ||
892 | u64 size, int target, int access, u32 type, | ||
893 | u32 comp, struct nouveau_gpuobj **pobj); | ||
894 | extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset, | ||
895 | int class, u64 base, u64 size, int target, | ||
896 | int access, u32 type, u32 comp); | ||
895 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, | 897 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, |
896 | struct drm_file *); | 898 | struct drm_file *); |
897 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, | 899 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, |
@@ -1545,6 +1547,22 @@ nv_match_device(struct drm_device *dev, unsigned device, | |||
1545 | dev->pdev->subsystem_device == sub_device; | 1547 | dev->pdev->subsystem_device == sub_device; |
1546 | } | 1548 | } |
1547 | 1549 | ||
1550 | /* memory type/access flags, do not match hardware values */ | ||
1551 | #define NV_MEM_ACCESS_RO 1 | ||
1552 | #define NV_MEM_ACCESS_WO 2 | ||
1553 | #define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO) | ||
1554 | #define NV_MEM_ACCESS_VM 4 | ||
1555 | |||
1556 | #define NV_MEM_TARGET_VRAM 0 | ||
1557 | #define NV_MEM_TARGET_PCI 1 | ||
1558 | #define NV_MEM_TARGET_PCI_NOSNOOP 2 | ||
1559 | #define NV_MEM_TARGET_VM 3 | ||
1560 | #define NV_MEM_TARGET_GART 4 | ||
1561 | |||
1562 | #define NV_MEM_TYPE_VM 0x7f | ||
1563 | #define NV_MEM_COMP_VM 0x03 | ||
1564 | |||
1565 | /* NV_SW object class */ | ||
1548 | #define NV_SW 0x0000506e | 1566 | #define NV_SW 0x0000506e |
1549 | #define NV_SW_DMA_SEMAPHORE 0x00000060 | 1567 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
1550 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 | 1568 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 91aa6c54cc96..2579fc69d182 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -459,8 +459,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
459 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 459 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
460 | mem->start << PAGE_SHIFT, | 460 | mem->start << PAGE_SHIFT, |
461 | mem->size << PAGE_SHIFT, | 461 | mem->size << PAGE_SHIFT, |
462 | NV_DMA_ACCESS_RW, | 462 | NV_MEM_ACCESS_RW, |
463 | NV_DMA_TARGET_VIDMEM, &obj); | 463 | NV_MEM_TARGET_VRAM, &obj); |
464 | if (ret) | 464 | if (ret) |
465 | return ret; | 465 | return ret; |
466 | 466 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 2c5a1f66f7f0..a050b7b69782 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -99,7 +99,6 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
99 | int size, uint32_t *b_offset) | 99 | int size, uint32_t *b_offset) |
100 | { | 100 | { |
101 | struct drm_device *dev = chan->dev; | 101 | struct drm_device *dev = chan->dev; |
102 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
103 | struct nouveau_gpuobj *nobj = NULL; | 102 | struct nouveau_gpuobj *nobj = NULL; |
104 | struct drm_mm_node *mem; | 103 | struct drm_mm_node *mem; |
105 | uint32_t offset; | 104 | uint32_t offset; |
@@ -113,31 +112,15 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
113 | return -ENOMEM; | 112 | return -ENOMEM; |
114 | } | 113 | } |
115 | 114 | ||
116 | offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; | 115 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) |
117 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) { | 116 | target = NV_MEM_TARGET_VRAM; |
118 | target = NV_DMA_TARGET_VIDMEM; | 117 | else |
119 | } else | 118 | target = NV_MEM_TARGET_GART; |
120 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) { | 119 | offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; |
121 | if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && | ||
122 | dev_priv->card_type < NV_50) { | ||
123 | ret = nouveau_sgdma_get_page(dev, offset, &offset); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | target = NV_DMA_TARGET_PCI; | ||
127 | } else { | ||
128 | target = NV_DMA_TARGET_AGP; | ||
129 | if (dev_priv->card_type >= NV_50) | ||
130 | offset += dev_priv->vm_gart_base; | ||
131 | } | ||
132 | } else { | ||
133 | NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", | ||
134 | chan->notifier_bo->bo.mem.mem_type); | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | offset += mem->start; | 120 | offset += mem->start; |
138 | 121 | ||
139 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, | 122 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, |
140 | mem->size, NV_DMA_ACCESS_RW, target, | 123 | mem->size, NV_MEM_ACCESS_RW, target, |
141 | &nobj); | 124 | &nobj); |
142 | if (ret) { | 125 | if (ret) { |
143 | drm_mm_put_block(mem); | 126 | drm_mm_put_block(mem); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index e8c74de905ec..924653c30783 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -404,113 +404,157 @@ nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) | |||
404 | The method below creates a DMA object in instance RAM and returns a handle | 404 | The method below creates a DMA object in instance RAM and returns a handle |
405 | to it that can be used to set up context objects. | 405 | to it that can be used to set up context objects. |
406 | */ | 406 | */ |
407 | int | 407 | |
408 | nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, | 408 | void |
409 | uint64_t offset, uint64_t size, int access, | 409 | nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class, |
410 | int target, struct nouveau_gpuobj **gpuobj) | 410 | u64 base, u64 size, int target, int access, |
411 | u32 type, u32 comp) | ||
411 | { | 412 | { |
412 | struct drm_device *dev = chan->dev; | 413 | struct drm_nouveau_private *dev_priv = obj->dev->dev_private; |
413 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 414 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; |
414 | struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; | 415 | u32 flags0; |
415 | int ret; | ||
416 | 416 | ||
417 | NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n", | 417 | flags0 = (comp << 29) | (type << 22) | class; |
418 | chan->id, class, offset, size); | 418 | flags0 |= 0x00100000; |
419 | NV_DEBUG(dev, "access=%d target=%d\n", access, target); | 419 | |
420 | switch (access) { | ||
421 | case NV_MEM_ACCESS_RO: flags0 |= 0x00040000; break; | ||
422 | case NV_MEM_ACCESS_RW: | ||
423 | case NV_MEM_ACCESS_WO: flags0 |= 0x00080000; break; | ||
424 | default: | ||
425 | break; | ||
426 | } | ||
420 | 427 | ||
421 | switch (target) { | 428 | switch (target) { |
422 | case NV_DMA_TARGET_AGP: | 429 | case NV_MEM_TARGET_VRAM: |
423 | offset += dev_priv->gart_info.aper_base; | 430 | flags0 |= 0x00010000; |
431 | break; | ||
432 | case NV_MEM_TARGET_PCI: | ||
433 | flags0 |= 0x00020000; | ||
434 | break; | ||
435 | case NV_MEM_TARGET_PCI_NOSNOOP: | ||
436 | flags0 |= 0x00030000; | ||
424 | break; | 437 | break; |
438 | case NV_MEM_TARGET_GART: | ||
439 | base += dev_priv->vm_gart_base; | ||
425 | default: | 440 | default: |
441 | flags0 &= ~0x00100000; | ||
426 | break; | 442 | break; |
427 | } | 443 | } |
428 | 444 | ||
429 | ret = nouveau_gpuobj_new(dev, chan, | 445 | /* convert to base + limit */ |
430 | nouveau_gpuobj_class_instmem_size(dev, class), | 446 | size = (base + size) - 1; |
431 | 16, NVOBJ_FLAG_ZERO_ALLOC | | ||
432 | NVOBJ_FLAG_ZERO_FREE, gpuobj); | ||
433 | if (ret) { | ||
434 | NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); | ||
435 | return ret; | ||
436 | } | ||
437 | 447 | ||
438 | if (dev_priv->card_type < NV_50) { | 448 | nv_wo32(obj, offset + 0x00, flags0); |
439 | uint32_t frame, adjust, pte_flags = 0; | 449 | nv_wo32(obj, offset + 0x04, lower_32_bits(size)); |
440 | 450 | nv_wo32(obj, offset + 0x08, lower_32_bits(base)); | |
441 | if (access != NV_DMA_ACCESS_RO) | 451 | nv_wo32(obj, offset + 0x0c, upper_32_bits(size) << 24 | |
442 | pte_flags |= (1<<1); | 452 | upper_32_bits(base)); |
443 | adjust = offset & 0x00000fff; | 453 | nv_wo32(obj, offset + 0x10, 0x00000000); |
444 | frame = offset & ~0x00000fff; | 454 | nv_wo32(obj, offset + 0x14, 0x00000000); |
445 | |||
446 | nv_wo32(*gpuobj, 0, ((1<<12) | (1<<13) | (adjust << 20) | | ||
447 | (access << 14) | (target << 16) | | ||
448 | class)); | ||
449 | nv_wo32(*gpuobj, 4, size - 1); | ||
450 | nv_wo32(*gpuobj, 8, frame | pte_flags); | ||
451 | nv_wo32(*gpuobj, 12, frame | pte_flags); | ||
452 | } else { | ||
453 | uint64_t limit = offset + size - 1; | ||
454 | uint32_t flags0, flags5; | ||
455 | 455 | ||
456 | if (target == NV_DMA_TARGET_VIDMEM) { | 456 | pinstmem->flush(obj->dev); |
457 | flags0 = 0x00190000; | 457 | } |
458 | flags5 = 0x00010000; | ||
459 | } else { | ||
460 | flags0 = 0x7fc00000; | ||
461 | flags5 = 0x00080000; | ||
462 | } | ||
463 | 458 | ||
464 | nv_wo32(*gpuobj, 0, flags0 | class); | 459 | int |
465 | nv_wo32(*gpuobj, 4, lower_32_bits(limit)); | 460 | nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size, |
466 | nv_wo32(*gpuobj, 8, lower_32_bits(offset)); | 461 | int target, int access, u32 type, u32 comp, |
467 | nv_wo32(*gpuobj, 12, ((upper_32_bits(limit) & 0xff) << 24) | | 462 | struct nouveau_gpuobj **pobj) |
468 | (upper_32_bits(offset) & 0xff)); | 463 | { |
469 | nv_wo32(*gpuobj, 20, flags5); | 464 | struct drm_device *dev = chan->dev; |
470 | } | 465 | int ret; |
471 | 466 | ||
472 | instmem->flush(dev); | 467 | ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_ALLOC | |
468 | NVOBJ_FLAG_ZERO_FREE, pobj); | ||
469 | if (ret) | ||
470 | return ret; | ||
473 | 471 | ||
474 | (*gpuobj)->engine = NVOBJ_ENGINE_SW; | 472 | nv50_gpuobj_dma_init(*pobj, 0, class, base, size, target, |
475 | (*gpuobj)->class = class; | 473 | access, type, comp); |
476 | return 0; | 474 | return 0; |
477 | } | 475 | } |
478 | 476 | ||
479 | int | 477 | int |
480 | nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, | 478 | nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, |
481 | uint64_t offset, uint64_t size, int access, | 479 | u64 size, int access, int target, |
482 | struct nouveau_gpuobj **gpuobj, | 480 | struct nouveau_gpuobj **pobj) |
483 | uint32_t *o_ret) | ||
484 | { | 481 | { |
482 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; | ||
485 | struct drm_device *dev = chan->dev; | 483 | struct drm_device *dev = chan->dev; |
486 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 484 | struct nouveau_gpuobj *obj; |
485 | u32 page_addr, flags0, flags2; | ||
487 | int ret; | 486 | int ret; |
488 | 487 | ||
489 | if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || | 488 | if (dev_priv->card_type >= NV_50) { |
490 | (dev_priv->card_type >= NV_50 && | 489 | u32 comp = (target == NV_MEM_TARGET_VM) ? NV_MEM_COMP_VM : 0; |
491 | dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { | 490 | u32 type = (target == NV_MEM_TARGET_VM) ? NV_MEM_TYPE_VM : 0; |
492 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 491 | |
493 | offset + dev_priv->vm_gart_base, | 492 | return nv50_gpuobj_dma_new(chan, class, base, size, |
494 | size, access, NV_DMA_TARGET_AGP, | 493 | target, access, type, comp, pobj); |
495 | gpuobj); | 494 | } |
496 | if (o_ret) | 495 | |
497 | *o_ret = 0; | 496 | if (target == NV_MEM_TARGET_GART) { |
498 | } else | 497 | if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { |
499 | if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { | 498 | target = NV_MEM_TARGET_PCI_NOSNOOP; |
500 | nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, gpuobj); | 499 | base += dev_priv->gart_info.aper_base; |
501 | if (offset & ~0xffffffffULL) { | 500 | } else |
502 | NV_ERROR(dev, "obj offset exceeds 32-bits\n"); | 501 | if (base != 0) { |
503 | return -EINVAL; | 502 | ret = nouveau_sgdma_get_page(dev, base, &page_addr); |
503 | if (ret) | ||
504 | return ret; | ||
505 | |||
506 | target = NV_MEM_TARGET_PCI; | ||
507 | base = page_addr; | ||
508 | } else { | ||
509 | nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, pobj); | ||
510 | return 0; | ||
504 | } | 511 | } |
505 | if (o_ret) | ||
506 | *o_ret = (uint32_t)offset; | ||
507 | ret = (*gpuobj != NULL) ? 0 : -EINVAL; | ||
508 | } else { | ||
509 | NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); | ||
510 | return -EINVAL; | ||
511 | } | 512 | } |
512 | 513 | ||
513 | return ret; | 514 | flags0 = class; |
515 | flags0 |= 0x00003000; /* PT present, PT linear */ | ||
516 | flags2 = 0; | ||
517 | |||
518 | switch (target) { | ||
519 | case NV_MEM_TARGET_PCI: | ||
520 | flags0 |= 0x00020000; | ||
521 | break; | ||
522 | case NV_MEM_TARGET_PCI_NOSNOOP: | ||
523 | flags0 |= 0x00030000; | ||
524 | break; | ||
525 | default: | ||
526 | break; | ||
527 | } | ||
528 | |||
529 | switch (access) { | ||
530 | case NV_MEM_ACCESS_RO: | ||
531 | flags0 |= 0x00004000; | ||
532 | break; | ||
533 | case NV_MEM_ACCESS_WO: | ||
534 | flags0 |= 0x00008000; | ||
535 | default: | ||
536 | flags2 |= 0x00000002; | ||
537 | break; | ||
538 | } | ||
539 | |||
540 | flags0 |= (base & 0x00000fff) << 20; | ||
541 | flags2 |= (base & 0xfffff000); | ||
542 | |||
543 | ret = nouveau_gpuobj_new(dev, chan, (dev_priv->card_type >= NV_40) ? | ||
544 | 32 : 16, 16, NVOBJ_FLAG_ZERO_ALLOC | | ||
545 | NVOBJ_FLAG_ZERO_FREE, &obj); | ||
546 | if (ret) | ||
547 | return ret; | ||
548 | |||
549 | nv_wo32(obj, 0x00, flags0); | ||
550 | nv_wo32(obj, 0x04, size - 1); | ||
551 | nv_wo32(obj, 0x08, flags2); | ||
552 | nv_wo32(obj, 0x0c, flags2); | ||
553 | |||
554 | obj->engine = NVOBJ_ENGINE_SW; | ||
555 | obj->class = class; | ||
556 | *pobj = obj; | ||
557 | return 0; | ||
514 | } | 558 | } |
515 | 559 | ||
516 | /* Context objects in the instance RAM have the following structure. | 560 | /* Context objects in the instance RAM have the following structure. |
@@ -806,8 +850,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
806 | if (dev_priv->card_type >= NV_50) { | 850 | if (dev_priv->card_type >= NV_50) { |
807 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 851 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
808 | 0, dev_priv->vm_end, | 852 | 0, dev_priv->vm_end, |
809 | NV_DMA_ACCESS_RW, | 853 | NV_MEM_ACCESS_RW, |
810 | NV_DMA_TARGET_AGP, &vram); | 854 | NV_MEM_TARGET_VM, &vram); |
811 | if (ret) { | 855 | if (ret) { |
812 | NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); | 856 | NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); |
813 | return ret; | 857 | return ret; |
@@ -815,8 +859,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
815 | } else { | 859 | } else { |
816 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 860 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
817 | 0, dev_priv->fb_available_size, | 861 | 0, dev_priv->fb_available_size, |
818 | NV_DMA_ACCESS_RW, | 862 | NV_MEM_ACCESS_RW, |
819 | NV_DMA_TARGET_VIDMEM, &vram); | 863 | NV_MEM_TARGET_VRAM, &vram); |
820 | if (ret) { | 864 | if (ret) { |
821 | NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); | 865 | NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); |
822 | return ret; | 866 | return ret; |
@@ -834,20 +878,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, | |||
834 | if (dev_priv->card_type >= NV_50) { | 878 | if (dev_priv->card_type >= NV_50) { |
835 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, | 879 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
836 | 0, dev_priv->vm_end, | 880 | 0, dev_priv->vm_end, |
837 | NV_DMA_ACCESS_RW, | 881 | NV_MEM_ACCESS_RW, |
838 | NV_DMA_TARGET_AGP, &tt); | 882 | NV_MEM_TARGET_VM, &tt); |
839 | if (ret) { | ||
840 | NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); | ||
841 | return ret; | ||
842 | } | ||
843 | } else | ||
844 | if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { | ||
845 | ret = nouveau_gpuobj_gart_dma_new(chan, 0, | ||
846 | dev_priv->gart_info.aper_size, | ||
847 | NV_DMA_ACCESS_RW, &tt, NULL); | ||
848 | } else { | 883 | } else { |
849 | NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); | 884 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, |
850 | ret = -EINVAL; | 885 | 0, dev_priv->gart_info.aper_size, |
886 | NV_MEM_ACCESS_RW, | ||
887 | NV_MEM_TARGET_GART, &tt); | ||
851 | } | 888 | } |
852 | 889 | ||
853 | if (ret) { | 890 | if (ret) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index df3a87e792f2..04e8fb795269 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -79,17 +79,6 @@ | |||
79 | # define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 | 79 | # define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 |
80 | # define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 | 80 | # define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 |
81 | 81 | ||
82 | /* DMA object defines */ | ||
83 | #define NV_DMA_ACCESS_RW 0 | ||
84 | #define NV_DMA_ACCESS_RO 1 | ||
85 | #define NV_DMA_ACCESS_WO 2 | ||
86 | #define NV_DMA_TARGET_VIDMEM 0 | ||
87 | #define NV_DMA_TARGET_PCI 2 | ||
88 | #define NV_DMA_TARGET_AGP 3 | ||
89 | /* The following is not a real value used by the card, it's changed by | ||
90 | * nouveau_object_dma_create */ | ||
91 | #define NV_DMA_TARGET_PCI_NONLINEAR 8 | ||
92 | |||
93 | /* Some object classes we care about in the drm */ | 82 | /* Some object classes we care about in the drm */ |
94 | #define NV_CLASS_DMA_FROM_MEMORY 0x00000002 | 83 | #define NV_CLASS_DMA_FROM_MEMORY 0x00000002 |
95 | #define NV_CLASS_DMA_TO_MEMORY 0x00000003 | 84 | #define NV_CLASS_DMA_TO_MEMORY 0x00000003 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 54af7608d45c..db32644f6114 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -247,14 +247,11 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
247 | */ | 247 | */ |
248 | gpuobj->cinst = gpuobj->pinst; | 248 | gpuobj->cinst = gpuobj->pinst; |
249 | 249 | ||
250 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | ||
251 | * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE | ||
252 | * on those cards? */ | ||
253 | nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | | 250 | nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | |
254 | (1 << 12) /* PT present */ | | 251 | (1 << 12) /* PT present */ | |
255 | (0 << 13) /* PT *not* linear */ | | 252 | (0 << 13) /* PT *not* linear */ | |
256 | (NV_DMA_ACCESS_RW << 14) | | 253 | (0 << 14) /* RW */ | |
257 | (NV_DMA_TARGET_PCI << 16)); | 254 | (2 << 16) /* PCI */); |
258 | nv_wo32(gpuobj, 4, aper_size - 1); | 255 | nv_wo32(gpuobj, 4, aper_size - 1); |
259 | for (i = 2; i < 2 + (aper_size >> 12); i++) | 256 | for (i = 2; i < 2 + (aper_size >> 12); i++) |
260 | nv_wo32(gpuobj, i * 4, 0x00000000); | 257 | nv_wo32(gpuobj, i * 4, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 35b28406caf6..e779e9320453 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -536,7 +536,7 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
536 | 536 | ||
537 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, | 537 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, |
538 | 0, dev_priv->vram_size, | 538 | 0, dev_priv->vram_size, |
539 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, | 539 | NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, |
540 | &gpuobj); | 540 | &gpuobj); |
541 | if (ret) | 541 | if (ret) |
542 | goto out_err; | 542 | goto out_err; |
@@ -546,9 +546,10 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
546 | if (ret) | 546 | if (ret) |
547 | goto out_err; | 547 | goto out_err; |
548 | 548 | ||
549 | ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, | 549 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, |
550 | dev_priv->gart_info.aper_size, | 550 | 0, dev_priv->gart_info.aper_size, |
551 | NV_DMA_ACCESS_RW, &gpuobj, NULL); | 551 | NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART, |
552 | &gpuobj); | ||
552 | if (ret) | 553 | if (ret) |
553 | goto out_err; | 554 | goto out_err; |
554 | 555 | ||