diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-30 17:27:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-30 17:27:01 -0400 |
commit | f698f1f7ad69f700dd1c754aa2b4aa7acbd51703 (patch) | |
tree | 53892eb15e0b2380d6c4e6f8321d0b8bea8de4c0 | |
parent | a77df5cd1cde203ef11c8e5a3ca47def5f5a1687 (diff) | |
parent | 6876b3bacaaa4c73fb8752b47c84b2b7fad5422a (diff) |
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm: fix for non-coherent DMA PowerPC
drm: radeon: fix sparse integer as NULL pointer warnings in radeon_mem.c
drm/i915: fix oops on agp=off
drm/r300: fix bug in r300 userspace hardware wait emission
-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; |