diff options
| -rw-r--r-- | drivers/char/drm/ati_pcigart.c | 6 | ||||
| -rw-r--r-- | drivers/char/drm/drm_scatter.c | 11 | ||||
| -rw-r--r-- | drivers/char/drm/drm_vm.c | 20 | ||||
| -rw-r--r-- | drivers/char/drm/i915_dma.c | 3 | ||||
| -rw-r--r-- | drivers/char/drm/r300_cmdbuf.c | 54 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drm.h | 12 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_mem.c | 8 |
7 files changed, 92 insertions, 22 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 35d25d821c38..141f4dfa0a11 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
| @@ -168,6 +168,12 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) | ||
| 172 | dma_sync_single_for_device(&dev->pdev->dev, | ||
| 173 | bus_address, | ||
| 174 | max_pages * sizeof(u32), | ||
| 175 | PCI_DMA_TODEVICE); | ||
| 176 | |||
| 171 | ret = 1; | 177 | ret = 1; |
| 172 | 178 | ||
| 173 | #if defined(__i386__) || defined(__x86_64__) | 179 | #if defined(__i386__) || defined(__x86_64__) |
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c index 26d8f675ed5d..b2b0f3d41714 100644 --- a/drivers/char/drm/drm_scatter.c +++ b/drivers/char/drm/drm_scatter.c | |||
| @@ -36,6 +36,15 @@ | |||
| 36 | 36 | ||
| 37 | #define DEBUG_SCATTER 0 | 37 | #define DEBUG_SCATTER 0 |
| 38 | 38 | ||
| 39 | static inline void *drm_vmalloc_dma(unsigned long size) | ||
| 40 | { | ||
| 41 | #if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) | ||
| 42 | return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE); | ||
| 43 | #else | ||
| 44 | return vmalloc_32(size); | ||
| 45 | #endif | ||
| 46 | } | ||
| 47 | |||
| 39 | void drm_sg_cleanup(struct drm_sg_mem * entry) | 48 | void drm_sg_cleanup(struct drm_sg_mem * entry) |
| 40 | { | 49 | { |
| 41 | struct page *page; | 50 | struct page *page; |
| @@ -104,7 +113,7 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) | |||
| 104 | } | 113 | } |
| 105 | memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); | 114 | memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); |
| 106 | 115 | ||
| 107 | entry->virtual = vmalloc_32(pages << PAGE_SHIFT); | 116 | entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); |
| 108 | if (!entry->virtual) { | 117 | if (!entry->virtual) { |
| 109 | drm_free(entry->busaddr, | 118 | drm_free(entry->busaddr, |
| 110 | entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); | 119 | entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 3d65c4dcd0c6..945df72a51a9 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
| @@ -54,13 +54,24 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) | |||
| 54 | pgprot_val(tmp) |= _PAGE_NO_CACHE; | 54 | pgprot_val(tmp) |= _PAGE_NO_CACHE; |
| 55 | if (map_type == _DRM_REGISTERS) | 55 | if (map_type == _DRM_REGISTERS) |
| 56 | pgprot_val(tmp) |= _PAGE_GUARDED; | 56 | pgprot_val(tmp) |= _PAGE_GUARDED; |
| 57 | #endif | 57 | #elif defined(__ia64__) |
| 58 | #if defined(__ia64__) | ||
| 59 | if (efi_range_is_wc(vma->vm_start, vma->vm_end - | 58 | if (efi_range_is_wc(vma->vm_start, vma->vm_end - |
| 60 | vma->vm_start)) | 59 | vma->vm_start)) |
| 61 | tmp = pgprot_writecombine(tmp); | 60 | tmp = pgprot_writecombine(tmp); |
| 62 | else | 61 | else |
| 63 | tmp = pgprot_noncached(tmp); | 62 | tmp = pgprot_noncached(tmp); |
| 63 | #elif defined(__sparc__) | ||
| 64 | tmp = pgprot_noncached(tmp); | ||
| 65 | #endif | ||
| 66 | return tmp; | ||
| 67 | } | ||
| 68 | |||
| 69 | static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma) | ||
| 70 | { | ||
| 71 | pgprot_t tmp = vm_get_page_prot(vma->vm_flags); | ||
| 72 | |||
| 73 | #if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) | ||
| 74 | tmp |= _PAGE_NO_CACHE; | ||
| 64 | #endif | 75 | #endif |
| 65 | return tmp; | 76 | return tmp; |
| 66 | } | 77 | } |
| @@ -603,9 +614,6 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
| 603 | offset = dev->driver->get_reg_ofs(dev); | 614 | offset = dev->driver->get_reg_ofs(dev); |
| 604 | vma->vm_flags |= VM_IO; /* not in core dump */ | 615 | vma->vm_flags |= VM_IO; /* not in core dump */ |
| 605 | vma->vm_page_prot = drm_io_prot(map->type, vma); | 616 | vma->vm_page_prot = drm_io_prot(map->type, vma); |
| 606 | #ifdef __sparc__ | ||
| 607 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
| 608 | #endif | ||
| 609 | if (io_remap_pfn_range(vma, vma->vm_start, | 617 | if (io_remap_pfn_range(vma, vma->vm_start, |
| 610 | (map->offset + offset) >> PAGE_SHIFT, | 618 | (map->offset + offset) >> PAGE_SHIFT, |
| 611 | vma->vm_end - vma->vm_start, | 619 | vma->vm_end - vma->vm_start, |
| @@ -624,6 +632,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
| 624 | page_to_pfn(virt_to_page(map->handle)), | 632 | page_to_pfn(virt_to_page(map->handle)), |
| 625 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 633 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) |
| 626 | return -EAGAIN; | 634 | return -EAGAIN; |
| 635 | vma->vm_page_prot = drm_dma_prot(map->type, vma); | ||
| 627 | /* fall through to _DRM_SHM */ | 636 | /* fall through to _DRM_SHM */ |
| 628 | case _DRM_SHM: | 637 | case _DRM_SHM: |
| 629 | vma->vm_ops = &drm_vm_shm_ops; | 638 | vma->vm_ops = &drm_vm_shm_ops; |
| @@ -631,6 +640,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
| 631 | /* Don't let this area swap. Change when | 640 | /* Don't let this area swap. Change when |
| 632 | DRM_KERNEL advisory is supported. */ | 641 | DRM_KERNEL advisory is supported. */ |
| 633 | vma->vm_flags |= VM_RESERVED; | 642 | vma->vm_flags |= VM_RESERVED; |
| 643 | vma->vm_page_prot = drm_dma_prot(map->type, vma); | ||
| 634 | break; | 644 | break; |
| 635 | case _DRM_SCATTER_GATHER: | 645 | case _DRM_SCATTER_GATHER: |
| 636 | vma->vm_ops = &drm_vm_sg_ops; | 646 | vma->vm_ops = &drm_vm_sg_ops; |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index e9d6663bec73..a043bb12301a 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
| @@ -804,6 +804,9 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
| 804 | { | 804 | { |
| 805 | drm_i915_private_t *dev_priv = dev->dev_private; | 805 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 806 | 806 | ||
| 807 | if (!dev_priv) | ||
| 808 | return; | ||
| 809 | |||
| 807 | if (dev_priv->agp_heap) | 810 | if (dev_priv->agp_heap) |
| 808 | i915_mem_takedown(&(dev_priv->agp_heap)); | 811 | i915_mem_takedown(&(dev_priv->agp_heap)); |
| 809 | 812 | ||
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 0f4afc44245c..f535812e4057 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
| @@ -729,6 +729,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf) | |||
| 729 | buf->used = 0; | 729 | buf->used = 0; |
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | static void r300_cmd_wait(drm_radeon_private_t * dev_priv, | ||
| 733 | drm_r300_cmd_header_t header) | ||
| 734 | { | ||
| 735 | u32 wait_until; | ||
| 736 | RING_LOCALS; | ||
| 737 | |||
| 738 | if (!header.wait.flags) | ||
| 739 | return; | ||
| 740 | |||
| 741 | wait_until = 0; | ||
| 742 | |||
| 743 | switch(header.wait.flags) { | ||
| 744 | case R300_WAIT_2D: | ||
| 745 | wait_until = RADEON_WAIT_2D_IDLE; | ||
| 746 | break; | ||
| 747 | case R300_WAIT_3D: | ||
| 748 | wait_until = RADEON_WAIT_3D_IDLE; | ||
| 749 | break; | ||
| 750 | case R300_NEW_WAIT_2D_3D: | ||
| 751 | wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE; | ||
| 752 | break; | ||
| 753 | case R300_NEW_WAIT_2D_2D_CLEAN: | ||
| 754 | wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; | ||
| 755 | break; | ||
| 756 | case R300_NEW_WAIT_3D_3D_CLEAN: | ||
| 757 | wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; | ||
| 758 | break; | ||
| 759 | case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: | ||
| 760 | wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; | ||
| 761 | wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; | ||
| 762 | break; | ||
| 763 | default: | ||
| 764 | return; | ||
| 765 | } | ||
| 766 | |||
| 767 | BEGIN_RING(2); | ||
| 768 | OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); | ||
| 769 | OUT_RING(wait_until); | ||
| 770 | ADVANCE_RING(); | ||
| 771 | } | ||
| 772 | |||
| 732 | static int r300_scratch(drm_radeon_private_t *dev_priv, | 773 | static int r300_scratch(drm_radeon_private_t *dev_priv, |
| 733 | drm_radeon_kcmd_buffer_t *cmdbuf, | 774 | drm_radeon_kcmd_buffer_t *cmdbuf, |
| 734 | drm_r300_cmd_header_t header) | 775 | drm_r300_cmd_header_t header) |
| @@ -909,19 +950,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, | |||
| 909 | break; | 950 | break; |
| 910 | 951 | ||
| 911 | case R300_CMD_WAIT: | 952 | case R300_CMD_WAIT: |
| 912 | /* simple enough, we can do it here */ | ||
| 913 | DRM_DEBUG("R300_CMD_WAIT\n"); | 953 | DRM_DEBUG("R300_CMD_WAIT\n"); |
| 914 | if (header.wait.flags == 0) | 954 | r300_cmd_wait(dev_priv, header); |
| 915 | break; /* nothing to do */ | ||
| 916 | |||
| 917 | { | ||
| 918 | RING_LOCALS; | ||
| 919 | |||
| 920 | BEGIN_RING(2); | ||
| 921 | OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); | ||
| 922 | OUT_RING((header.wait.flags & 0xf) << 14); | ||
| 923 | ADVANCE_RING(); | ||
| 924 | } | ||
| 925 | break; | 955 | break; |
| 926 | 956 | ||
| 927 | case R300_CMD_SCRATCH: | 957 | case R300_CMD_SCRATCH: |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 71e5b21fad2c..aab82e121e07 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
| @@ -225,8 +225,20 @@ typedef union { | |||
| 225 | #define R300_CMD_WAIT 7 | 225 | #define R300_CMD_WAIT 7 |
| 226 | # define R300_WAIT_2D 0x1 | 226 | # define R300_WAIT_2D 0x1 |
| 227 | # define R300_WAIT_3D 0x2 | 227 | # define R300_WAIT_3D 0x2 |
| 228 | /* these two defines are DOING IT WRONG - however | ||
| 229 | * we have userspace which relies on using these. | ||
| 230 | * The wait interface is backwards compat new | ||
| 231 | * code should use the NEW_WAIT defines below | ||
| 232 | * THESE ARE NOT BIT FIELDS | ||
| 233 | */ | ||
| 228 | # define R300_WAIT_2D_CLEAN 0x3 | 234 | # define R300_WAIT_2D_CLEAN 0x3 |
| 229 | # define R300_WAIT_3D_CLEAN 0x4 | 235 | # define R300_WAIT_3D_CLEAN 0x4 |
| 236 | |||
| 237 | # define R300_NEW_WAIT_2D_3D 0x3 | ||
| 238 | # define R300_NEW_WAIT_2D_2D_CLEAN 0x4 | ||
| 239 | # define R300_NEW_WAIT_3D_3D_CLEAN 0x6 | ||
| 240 | # define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8 | ||
| 241 | |||
| 230 | #define R300_CMD_SCRATCH 8 | 242 | #define R300_CMD_SCRATCH 8 |
| 231 | 243 | ||
| 232 | typedef union { | 244 | typedef union { |
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c index 78b34fa7c89a..4af5286a36fb 100644 --- a/drivers/char/drm/radeon_mem.c +++ b/drivers/char/drm/radeon_mem.c | |||
| @@ -88,7 +88,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size, | |||
| 88 | 88 | ||
| 89 | list_for_each(p, heap) { | 89 | list_for_each(p, heap) { |
| 90 | int start = (p->start + mask) & ~mask; | 90 | int start = (p->start + mask) & ~mask; |
| 91 | if (p->file_priv == 0 && start + size <= p->start + p->size) | 91 | if (p->file_priv == NULL && start + size <= p->start + p->size) |
| 92 | return split_block(p, start, size, file_priv); | 92 | return split_block(p, start, size, file_priv); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -113,7 +113,7 @@ static void free_block(struct mem_block *p) | |||
| 113 | /* Assumes a single contiguous range. Needs a special file_priv in | 113 | /* Assumes a single contiguous range. Needs a special file_priv in |
| 114 | * 'heap' to stop it being subsumed. | 114 | * 'heap' to stop it being subsumed. |
| 115 | */ | 115 | */ |
| 116 | if (p->next->file_priv == 0) { | 116 | if (p->next->file_priv == NULL) { |
| 117 | struct mem_block *q = p->next; | 117 | struct mem_block *q = p->next; |
| 118 | p->size += q->size; | 118 | p->size += q->size; |
| 119 | p->next = q->next; | 119 | p->next = q->next; |
| @@ -121,7 +121,7 @@ static void free_block(struct mem_block *p) | |||
| 121 | drm_free(q, sizeof(*q), DRM_MEM_BUFS); | 121 | drm_free(q, sizeof(*q), DRM_MEM_BUFS); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | if (p->prev->file_priv == 0) { | 124 | if (p->prev->file_priv == NULL) { |
| 125 | struct mem_block *q = p->prev; | 125 | struct mem_block *q = p->prev; |
| 126 | q->size += p->size; | 126 | q->size += p->size; |
| 127 | q->next = p->next; | 127 | q->next = p->next; |
| @@ -174,7 +174,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) | |||
| 174 | * 'heap' to stop it being subsumed. | 174 | * 'heap' to stop it being subsumed. |
| 175 | */ | 175 | */ |
| 176 | list_for_each(p, heap) { | 176 | list_for_each(p, heap) { |
| 177 | while (p->file_priv == 0 && p->next->file_priv == 0) { | 177 | while (p->file_priv == NULL && p->next->file_priv == NULL) { |
| 178 | struct mem_block *q = p->next; | 178 | struct mem_block *q = p->next; |
| 179 | p->size += q->size; | 179 | p->size += q->size; |
| 180 | p->next = q->next; | 180 | p->next = q->next; |
