aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm')
-rw-r--r--drivers/char/drm/drmP.h20
-rw-r--r--drivers/char/drm/drm_bufs.c20
-rw-r--r--drivers/char/drm/drm_dma.c4
-rw-r--r--drivers/char/drm/drm_drv.c4
-rw-r--r--drivers/char/drm/drm_memory.c173
-rw-r--r--drivers/char/drm/drm_memory.h128
-rw-r--r--drivers/char/drm/drm_memory_debug.h72
-rw-r--r--drivers/char/drm/drm_pci.c30
-rw-r--r--drivers/char/drm/drm_pciids.h116
-rw-r--r--drivers/char/drm/i915_dma.c2
-rw-r--r--drivers/char/drm/i915_irq.c2
-rw-r--r--drivers/char/drm/r300_cmdbuf.c86
-rw-r--r--drivers/char/drm/r300_reg.h39
-rw-r--r--drivers/char/drm/radeon_cp.c151
-rw-r--r--drivers/char/drm/radeon_drm.h5
-rw-r--r--drivers/char/drm/radeon_drv.h25
-rw-r--r--drivers/char/drm/radeon_state.c105
-rw-r--r--drivers/char/drm/sis_mm.c2
-rw-r--r--drivers/char/drm/via_irq.c12
19 files changed, 555 insertions, 441 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 107df9fdba4e..e1aadae00623 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -357,6 +357,12 @@ typedef struct drm_freelist {
357 spinlock_t lock; 357 spinlock_t lock;
358} drm_freelist_t; 358} drm_freelist_t;
359 359
360typedef struct drm_dma_handle {
361 dma_addr_t busaddr;
362 void *vaddr;
363 size_t size;
364} drm_dma_handle_t;
365
360/** 366/**
361 * Buffer entry. There is one of this for each buffer size order. 367 * Buffer entry. There is one of this for each buffer size order.
362 */ 368 */
@@ -366,7 +372,7 @@ typedef struct drm_buf_entry {
366 drm_buf_t *buflist; /**< buffer list */ 372 drm_buf_t *buflist; /**< buffer list */
367 int seg_count; 373 int seg_count;
368 int page_order; 374 int page_order;
369 unsigned long *seglist; 375 drm_dma_handle_t **seglist;
370 376
371 drm_freelist_t freelist; 377 drm_freelist_t freelist;
372} drm_buf_entry_t; 378} drm_buf_entry_t;
@@ -483,12 +489,6 @@ typedef struct drm_sigdata {
483 drm_hw_lock_t *lock; 489 drm_hw_lock_t *lock;
484} drm_sigdata_t; 490} drm_sigdata_t;
485 491
486typedef struct drm_dma_handle {
487 dma_addr_t busaddr;
488 void *vaddr;
489 size_t size;
490} drm_dma_handle_t;
491
492/** 492/**
493 * Mappings list 493 * Mappings list
494 */ 494 */
@@ -813,12 +813,8 @@ extern void drm_mem_init(void);
813extern int drm_mem_info(char *buf, char **start, off_t offset, 813extern int drm_mem_info(char *buf, char **start, off_t offset,
814 int request, int *eof, void *data); 814 int request, int *eof, void *data);
815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); 815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
816extern unsigned long drm_alloc_pages(int order, int area);
817extern void drm_free_pages(unsigned long address, int order, int area);
818extern void *drm_ioremap(unsigned long offset, unsigned long size, 816extern void *drm_ioremap(unsigned long offset, unsigned long size,
819 drm_device_t * dev); 817 drm_device_t * dev);
820extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
821 drm_device_t * dev);
822extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); 818extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
823 819
824extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); 820extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
@@ -1024,11 +1020,13 @@ static __inline__ void drm_core_ioremap(struct drm_map *map,
1024 map->handle = drm_ioremap(map->offset, map->size, dev); 1020 map->handle = drm_ioremap(map->offset, map->size, dev);
1025} 1021}
1026 1022
1023#if 0
1027static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, 1024static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
1028 struct drm_device *dev) 1025 struct drm_device *dev)
1029{ 1026{
1030 map->handle = drm_ioremap_nocache(map->offset, map->size, dev); 1027 map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
1031} 1028}
1029#endif /* 0 */
1032 1030
1033static __inline__ void drm_core_ioremapfree(struct drm_map *map, 1031static __inline__ void drm_core_ioremapfree(struct drm_map *map,
1034 struct drm_device *dev) 1032 struct drm_device *dev)
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index e2637b4d51de..8a9cf12e6183 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -474,8 +474,7 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
474 if (entry->seg_count) { 474 if (entry->seg_count) {
475 for (i = 0; i < entry->seg_count; i++) { 475 for (i = 0; i < entry->seg_count; i++) {
476 if (entry->seglist[i]) { 476 if (entry->seglist[i]) {
477 drm_free_pages(entry->seglist[i], 477 drm_pci_free(dev, entry->seglist[i]);
478 entry->page_order, DRM_MEM_DMA);
479 } 478 }
480 } 479 }
481 drm_free(entry->seglist, 480 drm_free(entry->seglist,
@@ -678,7 +677,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
678 int total; 677 int total;
679 int page_order; 678 int page_order;
680 drm_buf_entry_t *entry; 679 drm_buf_entry_t *entry;
681 unsigned long page; 680 drm_dma_handle_t *dmah;
682 drm_buf_t *buf; 681 drm_buf_t *buf;
683 int alignment; 682 int alignment;
684 unsigned long offset; 683 unsigned long offset;
@@ -781,8 +780,10 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
781 page_count = 0; 780 page_count = 0;
782 781
783 while (entry->buf_count < count) { 782 while (entry->buf_count < count) {
784 page = drm_alloc_pages(page_order, DRM_MEM_DMA); 783
785 if (!page) { 784 dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful);
785
786 if (!dmah) {
786 /* Set count correctly so we free the proper amount. */ 787 /* Set count correctly so we free the proper amount. */
787 entry->buf_count = count; 788 entry->buf_count = count;
788 entry->seg_count = count; 789 entry->seg_count = count;
@@ -794,13 +795,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
794 atomic_dec(&dev->buf_alloc); 795 atomic_dec(&dev->buf_alloc);
795 return -ENOMEM; 796 return -ENOMEM;
796 } 797 }
797 entry->seglist[entry->seg_count++] = page; 798 entry->seglist[entry->seg_count++] = dmah;
798 for (i = 0; i < (1 << page_order); i++) { 799 for (i = 0; i < (1 << page_order); i++) {
799 DRM_DEBUG("page %d @ 0x%08lx\n", 800 DRM_DEBUG("page %d @ 0x%08lx\n",
800 dma->page_count + page_count, 801 dma->page_count + page_count,
801 page + PAGE_SIZE * i); 802 (unsigned long)dmah->vaddr + PAGE_SIZE * i);
802 temp_pagelist[dma->page_count + page_count++] 803 temp_pagelist[dma->page_count + page_count++]
803 = page + PAGE_SIZE * i; 804 = (unsigned long)dmah->vaddr + PAGE_SIZE * i;
804 } 805 }
805 for (offset = 0; 806 for (offset = 0;
806 offset + size <= total && entry->buf_count < count; 807 offset + size <= total && entry->buf_count < count;
@@ -811,7 +812,8 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
811 buf->order = order; 812 buf->order = order;
812 buf->used = 0; 813 buf->used = 0;
813 buf->offset = (dma->byte_count + byte_count + offset); 814 buf->offset = (dma->byte_count + byte_count + offset);
814 buf->address = (void *)(page + offset); 815 buf->address = (void *)(dmah->vaddr + offset);
816 buf->bus_address = dmah->busaddr + offset;
815 buf->next = NULL; 817 buf->next = NULL;
816 buf->waiting = 0; 818 buf->waiting = 0;
817 buf->pending = 0; 819 buf->pending = 0;
diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
index 2afab95ca036..892db7096986 100644
--- a/drivers/char/drm/drm_dma.c
+++ b/drivers/char/drm/drm_dma.c
@@ -85,9 +85,7 @@ void drm_dma_takedown(drm_device_t * dev)
85 dma->bufs[i].seg_count); 85 dma->bufs[i].seg_count);
86 for (j = 0; j < dma->bufs[i].seg_count; j++) { 86 for (j = 0; j < dma->bufs[i].seg_count; j++) {
87 if (dma->bufs[i].seglist[j]) { 87 if (dma->bufs[i].seglist[j]) {
88 drm_free_pages(dma->bufs[i].seglist[j], 88 drm_pci_free(dev, dma->bufs[i].seglist[j]);
89 dma->bufs[i].page_order,
90 DRM_MEM_DMA);
91 } 89 }
92 } 90 }
93 drm_free(dma->bufs[i].seglist, 91 drm_free(dma->bufs[i].seglist,
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index dc6bbe8a18dc..3c0b882a8e72 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -75,8 +75,8 @@ static drm_ioctl_desc_t drm_ioctls[] = {
75 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 75 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
76 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, 76 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
77 77
78 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 78 [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY},
79 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 79 [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_ROOT_ONLY},
80 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 80 [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
81 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, 81 [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
82 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 82 [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index 8074771e348f..7e3318e1d1c6 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -79,66 +79,72 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
79 return pt; 79 return pt;
80} 80}
81 81
82/** 82#if __OS_HAS_AGP
83 * Allocate pages. 83/*
84 * 84 * Find the drm_map that covers the range [offset, offset+size).
85 * \param order size order.
86 * \param area memory area. (Not used.)
87 * \return page address on success, or zero on failure.
88 *
89 * Allocate and reserve free pages.
90 */ 85 */
91unsigned long drm_alloc_pages(int order, int area) 86static drm_map_t *drm_lookup_map(unsigned long offset,
87 unsigned long size, drm_device_t * dev)
92{ 88{
93 unsigned long address; 89 struct list_head *list;
94 unsigned long bytes = PAGE_SIZE << order; 90 drm_map_list_t *r_list;
95 unsigned long addr; 91 drm_map_t *map;
96 unsigned int sz; 92
97 93 list_for_each(list, &dev->maplist->head) {
98 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); 94 r_list = (drm_map_list_t *) list;
99 if (!address) 95 map = r_list->map;
100 return 0; 96 if (!map)
101 97 continue;
102 /* Zero */ 98 if (map->offset <= offset
103 memset((void *)address, 0, bytes); 99 && (offset + size) <= (map->offset + map->size))
104 100 return map;
105 /* Reserve */
106 for (addr = address, sz = bytes;
107 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
108 SetPageReserved(virt_to_page(addr));
109 } 101 }
110 102 return NULL;
111 return address;
112} 103}
113 104
114/** 105static void *agp_remap(unsigned long offset, unsigned long size,
115 * Free pages. 106 drm_device_t * dev)
116 *
117 * \param address address of the pages to free.
118 * \param order size order.
119 * \param area memory area. (Not used.)
120 *
121 * Unreserve and free pages allocated by alloc_pages().
122 */
123void drm_free_pages(unsigned long address, int order, int area)
124{ 107{
125 unsigned long bytes = PAGE_SIZE << order; 108 unsigned long *phys_addr_map, i, num_pages =
126 unsigned long addr; 109 PAGE_ALIGN(size) / PAGE_SIZE;
127 unsigned int sz; 110 struct drm_agp_mem *agpmem;
111 struct page **page_map;
112 void *addr;
113
114 size = PAGE_ALIGN(size);
115
116#ifdef __alpha__
117 offset -= dev->hose->mem_space->start;
118#endif
119
120 for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
121 if (agpmem->bound <= offset
122 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
123 (offset + size))
124 break;
125 if (!agpmem)
126 return NULL;
128 127
129 if (!address) 128 /*
130 return; 129 * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
130 * the CPU do not get remapped by the GART. We fix this by using the kernel's
131 * page-table instead (that's probably faster anyhow...).
132 */
133 /* note: use vmalloc() because num_pages could be large... */
134 page_map = vmalloc(num_pages * sizeof(struct page *));
135 if (!page_map)
136 return NULL;
131 137
132 /* Unreserve */ 138 phys_addr_map =
133 for (addr = address, sz = bytes; 139 agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
134 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { 140 for (i = 0; i < num_pages; ++i)
135 ClearPageReserved(virt_to_page(addr)); 141 page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
136 } 142 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
143 vfree(page_map);
137 144
138 free_pages(address, order); 145 return addr;
139} 146}
140 147
141#if __OS_HAS_AGP
142/** Wrapper around agp_allocate_memory() */ 148/** Wrapper around agp_allocate_memory() */
143DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) 149DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
144{ 150{
@@ -162,5 +168,74 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
162{ 168{
163 return drm_agp_unbind_memory(handle); 169 return drm_agp_unbind_memory(handle);
164} 170}
171
172#else /* __OS_HAS_AGP */
173
174static inline drm_map_t *drm_lookup_map(unsigned long offset,
175 unsigned long size, drm_device_t * dev)
176{
177 return NULL;
178}
179
180static inline void *agp_remap(unsigned long offset, unsigned long size,
181 drm_device_t * dev)
182{
183 return NULL;
184}
185
165#endif /* agp */ 186#endif /* agp */
187
188void *drm_ioremap(unsigned long offset, unsigned long size,
189 drm_device_t * dev)
190{
191 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
192 drm_map_t *map = drm_lookup_map(offset, size, dev);
193
194 if (map && map->type == _DRM_AGP)
195 return agp_remap(offset, size, dev);
196 }
197 return ioremap(offset, size);
198}
199EXPORT_SYMBOL(drm_ioremap);
200
201#if 0
202void *drm_ioremap_nocache(unsigned long offset,
203 unsigned long size, drm_device_t * dev)
204{
205 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
206 drm_map_t *map = drm_lookup_map(offset, size, dev);
207
208 if (map && map->type == _DRM_AGP)
209 return agp_remap(offset, size, dev);
210 }
211 return ioremap_nocache(offset, size);
212}
213#endif /* 0 */
214
215void drm_ioremapfree(void *pt, unsigned long size,
216 drm_device_t * dev)
217{
218 /*
219 * This is a bit ugly. It would be much cleaner if the DRM API would use separate
220 * routines for handling mappings in the AGP space. Hopefully this can be done in
221 * a future revision of the interface...
222 */
223 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
224 && ((unsigned long)pt >= VMALLOC_START
225 && (unsigned long)pt < VMALLOC_END)) {
226 unsigned long offset;
227 drm_map_t *map;
228
229 offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
230 map = drm_lookup_map(offset, size, dev);
231 if (map && map->type == _DRM_AGP) {
232 vunmap(pt);
233 return;
234 }
235 }
236
237 iounmap(pt);
238}
239EXPORT_SYMBOL(drm_ioremapfree);
240
166#endif /* debug_memory */ 241#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
index 3732a61c3762..714d9aedcff5 100644
--- a/drivers/char/drm/drm_memory.h
+++ b/drivers/char/drm/drm_memory.h
@@ -57,71 +57,6 @@
57# endif 57# endif
58#endif 58#endif
59 59
60/*
61 * Find the drm_map that covers the range [offset, offset+size).
62 */
63static inline drm_map_t *drm_lookup_map(unsigned long offset,
64 unsigned long size, drm_device_t * dev)
65{
66 struct list_head *list;
67 drm_map_list_t *r_list;
68 drm_map_t *map;
69
70 list_for_each(list, &dev->maplist->head) {
71 r_list = (drm_map_list_t *) list;
72 map = r_list->map;
73 if (!map)
74 continue;
75 if (map->offset <= offset
76 && (offset + size) <= (map->offset + map->size))
77 return map;
78 }
79 return NULL;
80}
81
82static inline void *agp_remap(unsigned long offset, unsigned long size,
83 drm_device_t * dev)
84{
85 unsigned long *phys_addr_map, i, num_pages =
86 PAGE_ALIGN(size) / PAGE_SIZE;
87 struct drm_agp_mem *agpmem;
88 struct page **page_map;
89 void *addr;
90
91 size = PAGE_ALIGN(size);
92
93#ifdef __alpha__
94 offset -= dev->hose->mem_space->start;
95#endif
96
97 for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
98 if (agpmem->bound <= offset
99 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
100 (offset + size))
101 break;
102 if (!agpmem)
103 return NULL;
104
105 /*
106 * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
107 * the CPU do not get remapped by the GART. We fix this by using the kernel's
108 * page-table instead (that's probably faster anyhow...).
109 */
110 /* note: use vmalloc() because num_pages could be large... */
111 page_map = vmalloc(num_pages * sizeof(struct page *));
112 if (!page_map)
113 return NULL;
114
115 phys_addr_map =
116 agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
117 for (i = 0; i < num_pages; ++i)
118 page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
119 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
120 vfree(page_map);
121
122 return addr;
123}
124
125static inline unsigned long drm_follow_page(void *vaddr) 60static inline unsigned long drm_follow_page(void *vaddr)
126{ 61{
127 pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); 62 pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
@@ -133,18 +68,6 @@ static inline unsigned long drm_follow_page(void *vaddr)
133 68
134#else /* __OS_HAS_AGP */ 69#else /* __OS_HAS_AGP */
135 70
136static inline drm_map_t *drm_lookup_map(unsigned long offset,
137 unsigned long size, drm_device_t * dev)
138{
139 return NULL;
140}
141
142static inline void *agp_remap(unsigned long offset, unsigned long size,
143 drm_device_t * dev)
144{
145 return NULL;
146}
147
148static inline unsigned long drm_follow_page(void *vaddr) 71static inline unsigned long drm_follow_page(void *vaddr)
149{ 72{
150 return 0; 73 return 0;
@@ -152,51 +75,8 @@ static inline unsigned long drm_follow_page(void *vaddr)
152 75
153#endif 76#endif
154 77
155static inline void *drm_ioremap(unsigned long offset, unsigned long size, 78void *drm_ioremap(unsigned long offset, unsigned long size,
156 drm_device_t * dev) 79 drm_device_t * dev);
157{
158 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
159 drm_map_t *map = drm_lookup_map(offset, size, dev);
160
161 if (map && map->type == _DRM_AGP)
162 return agp_remap(offset, size, dev);
163 }
164 return ioremap(offset, size);
165}
166
167static inline void *drm_ioremap_nocache(unsigned long offset,
168 unsigned long size, drm_device_t * dev)
169{
170 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
171 drm_map_t *map = drm_lookup_map(offset, size, dev);
172
173 if (map && map->type == _DRM_AGP)
174 return agp_remap(offset, size, dev);
175 }
176 return ioremap_nocache(offset, size);
177}
178
179static inline void drm_ioremapfree(void *pt, unsigned long size,
180 drm_device_t * dev)
181{
182 /*
183 * This is a bit ugly. It would be much cleaner if the DRM API would use separate
184 * routines for handling mappings in the AGP space. Hopefully this can be done in
185 * a future revision of the interface...
186 */
187 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
188 && ((unsigned long)pt >= VMALLOC_START
189 && (unsigned long)pt < VMALLOC_END)) {
190 unsigned long offset;
191 drm_map_t *map;
192
193 offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
194 map = drm_lookup_map(offset, size, dev);
195 if (map && map->type == _DRM_AGP) {
196 vunmap(pt);
197 return;
198 }
199 }
200 80
201 iounmap(pt); 81void drm_ioremapfree(void *pt, unsigned long size,
202} 82 drm_device_t * dev);
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index e84605fc54af..6543b9a14c42 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -206,76 +206,6 @@ void drm_free (void *pt, size_t size, int area) {
206 } 206 }
207} 207}
208 208
209unsigned long drm_alloc_pages (int order, int area) {
210 unsigned long address;
211 unsigned long bytes = PAGE_SIZE << order;
212 unsigned long addr;
213 unsigned int sz;
214
215 spin_lock(&drm_mem_lock);
216 if ((drm_ram_used >> PAGE_SHIFT)
217 > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
218 spin_unlock(&drm_mem_lock);
219 return 0;
220 }
221 spin_unlock(&drm_mem_lock);
222
223 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
224 if (!address) {
225 spin_lock(&drm_mem_lock);
226 ++drm_mem_stats[area].fail_count;
227 spin_unlock(&drm_mem_lock);
228 return 0;
229 }
230 spin_lock(&drm_mem_lock);
231 ++drm_mem_stats[area].succeed_count;
232 drm_mem_stats[area].bytes_allocated += bytes;
233 drm_ram_used += bytes;
234 spin_unlock(&drm_mem_lock);
235
236 /* Zero outside the lock */
237 memset((void *)address, 0, bytes);
238
239 /* Reserve */
240 for (addr = address, sz = bytes;
241 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
242 SetPageReserved(virt_to_page(addr));
243 }
244
245 return address;
246}
247
248void drm_free_pages (unsigned long address, int order, int area) {
249 unsigned long bytes = PAGE_SIZE << order;
250 int alloc_count;
251 int free_count;
252 unsigned long addr;
253 unsigned int sz;
254
255 if (!address) {
256 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
257 } else {
258 /* Unreserve */
259 for (addr = address, sz = bytes;
260 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
261 ClearPageReserved(virt_to_page(addr));
262 }
263 free_pages(address, order);
264 }
265
266 spin_lock(&drm_mem_lock);
267 free_count = ++drm_mem_stats[area].free_count;
268 alloc_count = drm_mem_stats[area].succeed_count;
269 drm_mem_stats[area].bytes_freed += bytes;
270 drm_ram_used -= bytes;
271 spin_unlock(&drm_mem_lock);
272 if (free_count > alloc_count) {
273 DRM_MEM_ERROR(area,
274 "Excess frees: %d frees, %d allocs\n",
275 free_count, alloc_count);
276 }
277}
278
279void *drm_ioremap (unsigned long offset, unsigned long size, 209void *drm_ioremap (unsigned long offset, unsigned long size,
280 drm_device_t * dev) { 210 drm_device_t * dev) {
281 void *pt; 211 void *pt;
@@ -299,6 +229,7 @@ void *drm_ioremap (unsigned long offset, unsigned long size,
299 return pt; 229 return pt;
300} 230}
301 231
232#if 0
302void *drm_ioremap_nocache (unsigned long offset, unsigned long size, 233void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
303 drm_device_t * dev) { 234 drm_device_t * dev) {
304 void *pt; 235 void *pt;
@@ -321,6 +252,7 @@ void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
321 spin_unlock(&drm_mem_lock); 252 spin_unlock(&drm_mem_lock);
322 return pt; 253 return pt;
323} 254}
255#endif /* 0 */
324 256
325void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { 257void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
326 int alloc_count; 258 int alloc_count;
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 1fd7ff164817..86a0f1c22091 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -37,6 +37,7 @@
37 */ 37 */
38 38
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/dma-mapping.h>
40#include "drmP.h" 41#include "drmP.h"
41 42
42/**********************************************************************/ 43/**********************************************************************/
@@ -50,6 +51,10 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
50 dma_addr_t maxaddr) 51 dma_addr_t maxaddr)
51{ 52{
52 drm_dma_handle_t *dmah; 53 drm_dma_handle_t *dmah;
54#if 1
55 unsigned long addr;
56 size_t sz;
57#endif
53#ifdef DRM_DEBUG_MEMORY 58#ifdef DRM_DEBUG_MEMORY
54 int area = DRM_MEM_DMA; 59 int area = DRM_MEM_DMA;
55 60
@@ -79,7 +84,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
79 return NULL; 84 return NULL;
80 85
81 dmah->size = size; 86 dmah->size = size;
82 dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); 87 dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP);
83 88
84#ifdef DRM_DEBUG_MEMORY 89#ifdef DRM_DEBUG_MEMORY
85 if (dmah->vaddr == NULL) { 90 if (dmah->vaddr == NULL) {
@@ -104,18 +109,29 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
104 109
105 memset(dmah->vaddr, 0, size); 110 memset(dmah->vaddr, 0, size);
106 111
112 /* XXX - Is virt_to_page() legal for consistent mem? */
113 /* Reserve */
114 for (addr = (unsigned long)dmah->vaddr, sz = size;
115 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
116 SetPageReserved(virt_to_page(addr));
117 }
118
107 return dmah; 119 return dmah;
108} 120}
109 121
110EXPORT_SYMBOL(drm_pci_alloc); 122EXPORT_SYMBOL(drm_pci_alloc);
111 123
112/** 124/**
113 * \brief Free a PCI consistent memory block with freeing its descriptor. 125 * \brief Free a PCI consistent memory block without freeing its descriptor.
114 * 126 *
115 * This function is for internal use in the Linux-specific DRM core code. 127 * This function is for internal use in the Linux-specific DRM core code.
116 */ 128 */
117void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) 129void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
118{ 130{
131#if 1
132 unsigned long addr;
133 size_t sz;
134#endif
119#ifdef DRM_DEBUG_MEMORY 135#ifdef DRM_DEBUG_MEMORY
120 int area = DRM_MEM_DMA; 136 int area = DRM_MEM_DMA;
121 int alloc_count; 137 int alloc_count;
@@ -127,8 +143,14 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
127 DRM_MEM_ERROR(area, "Attempt to free address 0\n"); 143 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
128#endif 144#endif
129 } else { 145 } else {
130 pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, 146 /* XXX - Is virt_to_page() legal for consistent mem? */
131 dmah->busaddr); 147 /* Unreserve */
148 for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
149 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
150 ClearPageReserved(virt_to_page(addr));
151 }
152 dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
153 dmah->busaddr);
132 } 154 }
133 155
134#ifdef DRM_DEBUG_MEMORY 156#ifdef DRM_DEBUG_MEMORY
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 2c17e88a8847..b1bb3c7b568d 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -3,49 +3,69 @@
3 Please contact dri-devel@lists.sf.net to add new cards to this list 3 Please contact dri-devel@lists.sf.net to add new cards to this list
4*/ 4*/
5#define radeon_PCI_IDS \ 5#define radeon_PCI_IDS \
6 {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ 6 {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
7 {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
8 {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
9 {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
10 {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
7 {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ 11 {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \
8 {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ 12 {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
9 {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 13 {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
10 {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 14 {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
11 {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 15 {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
12 {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 16 {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
17 {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
18 {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
19 {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
20 {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
13 {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 21 {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
14 {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 22 {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
15 {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 23 {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
16 {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 24 {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
17 {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 25 {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
26 {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
18 {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 27 {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
19 {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \ 28 {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
20 {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 29 {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
21 {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 30 {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
22 {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 31 {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
23 {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 32 {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
24 {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 33 {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
25 {0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 34 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
26 {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 35 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
27 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 36 {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
28 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 37 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
29 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 38 {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
30 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 39 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
40 {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
41 {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
42 {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
43 {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
44 {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
45 {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
46 {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
47 {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
48 {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
49 {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
31 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 50 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
32 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 51 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
33 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ 52 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
34 {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ 53 {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
35 {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 54 {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
36 {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 55 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
37 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 56 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
38 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
39 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 57 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
40 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 58 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
41 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 59 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
42 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 60 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
43 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 61 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
44 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 62 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
45 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 63 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
46 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 64 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
47 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 65 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
48 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 66 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
67 {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
68 {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
49 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 69 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
50 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 70 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
51 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 71 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
@@ -53,44 +73,66 @@
53 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 73 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
54 {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 74 {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
55 {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 75 {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
56 {0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
57 {0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
58 {0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
59 {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 76 {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
60 {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 77 {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
61 {0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
62 {0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
63 {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ 78 {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
64 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ 79 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
65 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 80 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
66 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 81 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
67 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 82 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
68 {0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 83 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
69 {0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 84 {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
70 {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 85 {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
71 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 86 {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
72 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 87 {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
73 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 88 {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
74 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 89 {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
90 {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
91 {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
92 {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
93 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
94 {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
95 {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
96 {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
97 {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
98 {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
99 {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
100 {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
101 {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
102 {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
75 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 103 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
76 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 104 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
77 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
78 {0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
79 {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 105 {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
80 {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 106 {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
81 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 107 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
82 {0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
83 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 108 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
84 {0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 109 {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
85 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 110 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
86 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 111 {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
87 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 112 {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
113 {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
114 {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
115 {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
88 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 116 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
89 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
90 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 117 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
91 {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 118 {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
92 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 119 {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
93 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 120 {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
121 {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
122 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
123 {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
124 {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
125 {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
126 {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
127 {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
128 {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
129 {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
130 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
131 {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
132 {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
133 {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
134 {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \
135 {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
94 {0, 0, 0} 136 {0, 0, 0}
95 137
96#define r128_PCI_IDS \ 138#define r128_PCI_IDS \
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 1ff4c7ca0bff..9f4b8ce4c05e 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -495,8 +495,6 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev,
495 } 495 }
496 } 496 }
497 497
498 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
499
500 i915_emit_breadcrumb(dev); 498 i915_emit_breadcrumb(dev);
501 499
502 return 0; 500 return 0;
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index d3879ac9970f..a752afd86ab8 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -53,6 +53,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
53 53
54 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 54 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
55 55
56 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
57
56 if (temp & USER_INT_FLAG) 58 if (temp & USER_INT_FLAG)
57 DRM_WAKEUP(&dev_priv->irq_queue); 59 DRM_WAKEUP(&dev_priv->irq_queue);
58 60
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index c08fa5076f05..b108c7f913b2 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -214,13 +214,13 @@ void r300_init_reg_flags(void)
214 ADD_RANGE(0x4F54, 1); 214 ADD_RANGE(0x4F54, 1);
215 215
216 ADD_RANGE(R300_TX_FILTER_0, 16); 216 ADD_RANGE(R300_TX_FILTER_0, 16);
217 ADD_RANGE(R300_TX_UNK1_0, 16); 217 ADD_RANGE(R300_TX_FILTER1_0, 16);
218 ADD_RANGE(R300_TX_SIZE_0, 16); 218 ADD_RANGE(R300_TX_SIZE_0, 16);
219 ADD_RANGE(R300_TX_FORMAT_0, 16); 219 ADD_RANGE(R300_TX_FORMAT_0, 16);
220 ADD_RANGE(R300_TX_PITCH_0, 16); 220 ADD_RANGE(R300_TX_PITCH_0, 16);
221 /* Texture offset is dangerous and needs more checking */ 221 /* Texture offset is dangerous and needs more checking */
222 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); 222 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
223 ADD_RANGE(R300_TX_UNK4_0, 16); 223 ADD_RANGE(R300_TX_CHROMA_KEY_0, 16);
224 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); 224 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
225 225
226 /* Sporadic registers used as primitives are emitted */ 226 /* Sporadic registers used as primitives are emitted */
@@ -242,8 +242,10 @@ static __inline__ int r300_check_range(unsigned reg, int count)
242 return 0; 242 return 0;
243} 243}
244 244
245 /* we expect offsets passed to the framebuffer to be either within video memory or 245/*
246 within AGP space */ 246 * we expect offsets passed to the framebuffer to be either within video
247 * memory or within AGP space
248 */
247static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, 249static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
248 u32 offset) 250 u32 offset)
249{ 251{
@@ -251,11 +253,11 @@ static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
251 but this value is not being kept. 253 but this value is not being kept.
252 This code is correct for now (does the same thing as the 254 This code is correct for now (does the same thing as the
253 code that sets MC_FB_LOCATION) in radeon_cp.c */ 255 code that sets MC_FB_LOCATION) in radeon_cp.c */
254 if ((offset >= dev_priv->fb_location) && 256 if (offset >= dev_priv->fb_location &&
255 (offset < dev_priv->gart_vm_start)) 257 offset < (dev_priv->fb_location + dev_priv->fb_size))
256 return 0; 258 return 0;
257 if ((offset >= dev_priv->gart_vm_start) && 259 if (offset >= dev_priv->gart_vm_start &&
258 (offset < dev_priv->gart_vm_start + dev_priv->gart_size)) 260 offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
259 return 0; 261 return 0;
260 return 1; 262 return 1;
261} 263}
@@ -490,6 +492,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
490 492
491 return 0; 493 return 0;
492} 494}
495
493static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, 496static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
494 drm_radeon_kcmd_buffer_t *cmdbuf) 497 drm_radeon_kcmd_buffer_t *cmdbuf)
495{ 498{
@@ -701,6 +704,64 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
701 buf->used = 0; 704 buf->used = 0;
702} 705}
703 706
707static int r300_scratch(drm_radeon_private_t *dev_priv,
708 drm_radeon_kcmd_buffer_t *cmdbuf,
709 drm_r300_cmd_header_t header)
710{
711 u32 *ref_age_base;
712 u32 i, buf_idx, h_pending;
713 RING_LOCALS;
714
715 if (cmdbuf->bufsz <
716 (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
717 return DRM_ERR(EINVAL);
718 }
719
720 if (header.scratch.reg >= 5) {
721 return DRM_ERR(EINVAL);
722 }
723
724 dev_priv->scratch_ages[header.scratch.reg]++;
725
726 ref_age_base = *(u32 **)cmdbuf->buf;
727
728 cmdbuf->buf += sizeof(u64);
729 cmdbuf->bufsz -= sizeof(u64);
730
731 for (i=0; i < header.scratch.n_bufs; i++) {
732 buf_idx = *(u32 *)cmdbuf->buf;
733 buf_idx *= 2; /* 8 bytes per buf */
734
735 if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
736 return DRM_ERR(EINVAL);
737 }
738
739 if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
740 return DRM_ERR(EINVAL);
741 }
742
743 if (h_pending == 0) {
744 return DRM_ERR(EINVAL);
745 }
746
747 h_pending--;
748
749 if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
750 return DRM_ERR(EINVAL);
751 }
752
753 cmdbuf->buf += sizeof(buf_idx);
754 cmdbuf->bufsz -= sizeof(buf_idx);
755 }
756
757 BEGIN_RING(2);
758 OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0));
759 OUT_RING(dev_priv->scratch_ages[header.scratch.reg]);
760 ADVANCE_RING();
761
762 return 0;
763}
764
704/** 765/**
705 * Parses and validates a user-supplied command buffer and emits appropriate 766 * Parses and validates a user-supplied command buffer and emits appropriate
706 * commands on the DMA ring buffer. 767 * commands on the DMA ring buffer.
@@ -838,6 +899,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev,
838 } 899 }
839 break; 900 break;
840 901
902 case R300_CMD_SCRATCH:
903 DRM_DEBUG("R300_CMD_SCRATCH\n");
904 ret = r300_scratch(dev_priv, cmdbuf, header);
905 if (ret) {
906 DRM_ERROR("r300_scratch failed\n");
907 goto cleanup;
908 }
909 break;
910
841 default: 911 default:
842 DRM_ERROR("bad cmd_type %i at %p\n", 912 DRM_ERROR("bad cmd_type %i at %p\n",
843 header.header.cmd_type, 913 header.header.cmd_type,
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index d1e19954406b..a881f96c983e 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -711,8 +711,22 @@ I am fairly certain that they are correct unless stated otherwise in comments.
711# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) 711# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
712# define R300_TX_MAX_ANISO_MASK (14 << 21) 712# define R300_TX_MAX_ANISO_MASK (14 << 21)
713 713
714#define R300_TX_UNK1_0 0x4440 714#define R300_TX_FILTER1_0 0x4440
715# define R300_CHROMA_KEY_MODE_DISABLE 0
716# define R300_CHROMA_KEY_FORCE 1
717# define R300_CHROMA_KEY_BLEND 2
718# define R300_MC_ROUND_NORMAL (0<<2)
719# define R300_MC_ROUND_MPEG4 (1<<2)
715# define R300_LOD_BIAS_MASK 0x1fff 720# define R300_LOD_BIAS_MASK 0x1fff
721# define R300_EDGE_ANISO_EDGE_DIAG (0<<13)
722# define R300_EDGE_ANISO_EDGE_ONLY (1<<13)
723# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14)
724# define R300_MC_COORD_TRUNCATE_MPEG (1<<14)
725# define R300_TX_TRI_PERF_0_8 (0<<15)
726# define R300_TX_TRI_PERF_1_8 (1<<15)
727# define R300_TX_TRI_PERF_1_4 (2<<15)
728# define R300_TX_TRI_PERF_3_8 (3<<15)
729# define R300_ANISO_THRESHOLD_MASK (7<<17)
716 730
717#define R300_TX_SIZE_0 0x4480 731#define R300_TX_SIZE_0 0x4480
718# define R300_TX_WIDTHMASK_SHIFT 0 732# define R300_TX_WIDTHMASK_SHIFT 0
@@ -722,6 +736,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
722# define R300_TX_UNK23 (1 << 23) 736# define R300_TX_UNK23 (1 << 23)
723# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ 737# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
724# define R300_TX_SIZE_MASK (15 << 26) 738# define R300_TX_SIZE_MASK (15 << 26)
739# define R300_TX_SIZE_PROJECTED (1<<30)
740# define R300_TX_SIZE_TXPITCH_EN (1<<31)
725#define R300_TX_FORMAT_0 0x44C0 741#define R300_TX_FORMAT_0 0x44C0
726 /* The interpretation of the format word by Wladimir van der Laan */ 742 /* The interpretation of the format word by Wladimir van der Laan */
727 /* The X, Y, Z and W refer to the layout of the components. 743 /* The X, Y, Z and W refer to the layout of the components.
@@ -750,7 +766,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
750# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ 766# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
751# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ 767# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
752 /* 0x16 - some 16 bit green format.. ?? */ 768 /* 0x16 - some 16 bit green format.. ?? */
753# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ 769# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
770# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
754 771
755 /* gap */ 772 /* gap */
756 /* Floating point formats */ 773 /* Floating point formats */
@@ -800,18 +817,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
800 817
801# define R300_TX_FORMAT_YUV_MODE 0x00800000 818# define R300_TX_FORMAT_YUV_MODE 0x00800000
802 819
803#define R300_TX_PITCH_0 0x4500 820#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */
804#define R300_TX_OFFSET_0 0x4540 821#define R300_TX_OFFSET_0 0x4540
805/* BEGIN: Guess from R200 */ 822/* BEGIN: Guess from R200 */
806# define R300_TXO_ENDIAN_NO_SWAP (0 << 0) 823# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
807# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) 824# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
808# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) 825# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
809# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) 826# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
827# define R300_TXO_MACRO_TILE (1 << 2)
828# define R300_TXO_MICRO_TILE (1 << 3)
810# define R300_TXO_OFFSET_MASK 0xffffffe0 829# define R300_TXO_OFFSET_MASK 0xffffffe0
811# define R300_TXO_OFFSET_SHIFT 5 830# define R300_TXO_OFFSET_SHIFT 5
812/* END */ 831/* END */
813#define R300_TX_UNK4_0 0x4580 832#define R300_TX_CHROMA_KEY_0 0x4580 /* 32 bit chroma key */
814#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } 833#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
815 834
816/* END */ 835/* END */
817 836
@@ -868,7 +887,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
868# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) 887# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
869# define R300_PFS_NODE_TEX_END_SHIFT 17 888# define R300_PFS_NODE_TEX_END_SHIFT 17
870# define R300_PFS_NODE_TEX_END_MASK (31 << 17) 889# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
871# define R300_PFS_NODE_LAST_NODE (1 << 22) 890/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */
891# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
892# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
872 893
873/* TEX 894/* TEX
874// As far as I can tell, texture instructions cannot write into output 895// As far as I can tell, texture instructions cannot write into output
@@ -887,6 +908,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
887 */ 908 */
888# define R300_FPITX_OPCODE_SHIFT 15 909# define R300_FPITX_OPCODE_SHIFT 15
889# define R300_FPITX_OP_TEX 1 910# define R300_FPITX_OP_TEX 1
911# define R300_FPITX_OP_KIL 2
890# define R300_FPITX_OP_TXP 3 912# define R300_FPITX_OP_TXP 3
891# define R300_FPITX_OP_TXB 4 913# define R300_FPITX_OP_TXB 4
892 914
@@ -962,9 +984,11 @@ I am fairly certain that they are correct unless stated otherwise in comments.
962# define R300_FPI1_SRC2C_CONST (1 << 17) 984# define R300_FPI1_SRC2C_CONST (1 << 17)
963# define R300_FPI1_DSTC_SHIFT 18 985# define R300_FPI1_DSTC_SHIFT 18
964# define R300_FPI1_DSTC_MASK (31 << 18) 986# define R300_FPI1_DSTC_MASK (31 << 18)
987# define R300_FPI1_DSTC_REG_MASK_SHIFT 23
965# define R300_FPI1_DSTC_REG_X (1 << 23) 988# define R300_FPI1_DSTC_REG_X (1 << 23)
966# define R300_FPI1_DSTC_REG_Y (1 << 24) 989# define R300_FPI1_DSTC_REG_Y (1 << 24)
967# define R300_FPI1_DSTC_REG_Z (1 << 25) 990# define R300_FPI1_DSTC_REG_Z (1 << 25)
991# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26
968# define R300_FPI1_DSTC_OUTPUT_X (1 << 26) 992# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
969# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) 993# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
970# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) 994# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
@@ -983,6 +1007,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
983# define R300_FPI3_DSTA_MASK (31 << 18) 1007# define R300_FPI3_DSTA_MASK (31 << 18)
984# define R300_FPI3_DSTA_REG (1 << 23) 1008# define R300_FPI3_DSTA_REG (1 << 23)
985# define R300_FPI3_DSTA_OUTPUT (1 << 24) 1009# define R300_FPI3_DSTA_OUTPUT (1 << 24)
1010# define R300_FPI3_DSTA_DEPTH (1 << 27)
986 1011
987#define R300_PFS_INSTR0_0 0x48C0 1012#define R300_PFS_INSTR0_0 0x48C0
988# define R300_FPI0_ARGC_SRC0C_XYZ 0 1013# define R300_FPI0_ARGC_SRC0C_XYZ 0
@@ -1036,7 +1061,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
1036# define R300_FPI0_OUTC_FRC (9 << 23) 1061# define R300_FPI0_OUTC_FRC (9 << 23)
1037# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) 1062# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
1038# define R300_FPI0_OUTC_SAT (1 << 30) 1063# define R300_FPI0_OUTC_SAT (1 << 30)
1039# define R300_FPI0_UNKNOWN_31 (1 << 31) 1064# define R300_FPI0_INSERT_NOP (1 << 31)
1040 1065
1041#define R300_PFS_INSTR2_0 0x49C0 1066#define R300_PFS_INSTR2_0 0x49C0
1042# define R300_FPI2_ARGA_SRC0C_X 0 1067# define R300_FPI2_ARGA_SRC0C_X 0
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 9bb8ae0c1c27..7f949c9c9691 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1118,14 +1118,20 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1118{ 1118{
1119 u32 ring_start, cur_read_ptr; 1119 u32 ring_start, cur_read_ptr;
1120 u32 tmp; 1120 u32 tmp;
1121 1121
1122 /* Initialize the memory controller */ 1122 /* Initialize the memory controller. With new memory map, the fb location
1123 RADEON_WRITE(RADEON_MC_FB_LOCATION, 1123 * is not changed, it should have been properly initialized already. Part
1124 ((dev_priv->gart_vm_start - 1) & 0xffff0000) 1124 * of the problem is that the code below is bogus, assuming the GART is
1125 | (dev_priv->fb_location >> 16)); 1125 * always appended to the fb which is not necessarily the case
1126 */
1127 if (!dev_priv->new_memmap)
1128 RADEON_WRITE(RADEON_MC_FB_LOCATION,
1129 ((dev_priv->gart_vm_start - 1) & 0xffff0000)
1130 | (dev_priv->fb_location >> 16));
1126 1131
1127#if __OS_HAS_AGP 1132#if __OS_HAS_AGP
1128 if (dev_priv->flags & CHIP_IS_AGP) { 1133 if (dev_priv->flags & CHIP_IS_AGP) {
1134 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1129 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 1135 RADEON_WRITE(RADEON_MC_AGP_LOCATION,
1130 (((dev_priv->gart_vm_start - 1 + 1136 (((dev_priv->gart_vm_start - 1 +
1131 dev_priv->gart_size) & 0xffff0000) | 1137 dev_priv->gart_size) & 0xffff0000) |
@@ -1153,8 +1159,6 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1153 1159
1154#if __OS_HAS_AGP 1160#if __OS_HAS_AGP
1155 if (dev_priv->flags & CHIP_IS_AGP) { 1161 if (dev_priv->flags & CHIP_IS_AGP) {
1156 /* set RADEON_AGP_BASE here instead of relying on X from user space */
1157 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1158 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 1162 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
1159 dev_priv->ring_rptr->offset 1163 dev_priv->ring_rptr->offset
1160 - dev->agp->base + dev_priv->gart_vm_start); 1164 - dev->agp->base + dev_priv->gart_vm_start);
@@ -1174,6 +1178,17 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1174 entry->handle + tmp_ofs); 1178 entry->handle + tmp_ofs);
1175 } 1179 }
1176 1180
1181 /* Set ring buffer size */
1182#ifdef __BIG_ENDIAN
1183 RADEON_WRITE(RADEON_CP_RB_CNTL,
1184 dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
1185#else
1186 RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
1187#endif
1188
1189 /* Start with assuming that writeback doesn't work */
1190 dev_priv->writeback_works = 0;
1191
1177 /* Initialize the scratch register pointer. This will cause 1192 /* Initialize the scratch register pointer. This will cause
1178 * the scratch register values to be written out to memory 1193 * the scratch register values to be written out to memory
1179 * whenever they are updated. 1194 * whenever they are updated.
@@ -1190,28 +1205,9 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1190 1205
1191 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); 1206 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
1192 1207
1193 /* Writeback doesn't seem to work everywhere, test it first */ 1208 /* Turn on bus mastering */
1194 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); 1209 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1195 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); 1210 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
1196
1197 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1198 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1199 0xdeadbeef)
1200 break;
1201 DRM_UDELAY(1);
1202 }
1203
1204 if (tmp < dev_priv->usec_timeout) {
1205 dev_priv->writeback_works = 1;
1206 DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp);
1207 } else {
1208 dev_priv->writeback_works = 0;
1209 DRM_DEBUG("writeback test failed\n");
1210 }
1211 if (radeon_no_wb == 1) {
1212 dev_priv->writeback_works = 0;
1213 DRM_DEBUG("writeback forced off\n");
1214 }
1215 1211
1216 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 1212 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
1217 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); 1213 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
@@ -1223,26 +1219,45 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1223 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 1219 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
1224 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); 1220 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
1225 1221
1226 /* Set ring buffer size */
1227#ifdef __BIG_ENDIAN
1228 RADEON_WRITE(RADEON_CP_RB_CNTL,
1229 dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
1230#else
1231 RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
1232#endif
1233
1234 radeon_do_wait_for_idle(dev_priv); 1222 radeon_do_wait_for_idle(dev_priv);
1235 1223
1236 /* Turn on bus mastering */
1237 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1238 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
1239
1240 /* Sync everything up */ 1224 /* Sync everything up */
1241 RADEON_WRITE(RADEON_ISYNC_CNTL, 1225 RADEON_WRITE(RADEON_ISYNC_CNTL,
1242 (RADEON_ISYNC_ANY2D_IDLE3D | 1226 (RADEON_ISYNC_ANY2D_IDLE3D |
1243 RADEON_ISYNC_ANY3D_IDLE2D | 1227 RADEON_ISYNC_ANY3D_IDLE2D |
1244 RADEON_ISYNC_WAIT_IDLEGUI | 1228 RADEON_ISYNC_WAIT_IDLEGUI |
1245 RADEON_ISYNC_CPSCRATCH_IDLEGUI)); 1229 RADEON_ISYNC_CPSCRATCH_IDLEGUI));
1230
1231}
1232
1233static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
1234{
1235 u32 tmp;
1236
1237 /* Writeback doesn't seem to work everywhere, test it here and possibly
1238 * enable it if it appears to work
1239 */
1240 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
1241 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
1242
1243 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1244 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1245 0xdeadbeef)
1246 break;
1247 DRM_UDELAY(1);
1248 }
1249
1250 if (tmp < dev_priv->usec_timeout) {
1251 dev_priv->writeback_works = 1;
1252 DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
1253 } else {
1254 dev_priv->writeback_works = 0;
1255 DRM_INFO("writeback test failed\n");
1256 }
1257 if (radeon_no_wb == 1) {
1258 dev_priv->writeback_works = 0;
1259 DRM_INFO("writeback forced off\n");
1260 }
1246} 1261}
1247 1262
1248/* Enable or disable PCI-E GART on the chip */ 1263/* Enable or disable PCI-E GART on the chip */
@@ -1317,6 +1332,14 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1317 1332
1318 DRM_DEBUG("\n"); 1333 DRM_DEBUG("\n");
1319 1334
1335 /* if we require new memory map but we don't have it fail */
1336 if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap)
1337 {
1338 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n");
1339 radeon_do_cleanup_cp(dev);
1340 return DRM_ERR(EINVAL);
1341 }
1342
1320 if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) 1343 if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
1321 { 1344 {
1322 DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1345 DRM_DEBUG("Forcing AGP card to PCI mode\n");
@@ -1496,6 +1519,9 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1496 1519
1497 dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) 1520 dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
1498 & 0xffff) << 16; 1521 & 0xffff) << 16;
1522 dev_priv->fb_size =
1523 ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
1524 - dev_priv->fb_location;
1499 1525
1500 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1526 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
1501 ((dev_priv->front_offset 1527 ((dev_priv->front_offset
@@ -1510,8 +1536,46 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1510 + dev_priv->fb_location) >> 10)); 1536 + dev_priv->fb_location) >> 10));
1511 1537
1512 dev_priv->gart_size = init->gart_size; 1538 dev_priv->gart_size = init->gart_size;
1513 dev_priv->gart_vm_start = dev_priv->fb_location 1539
1514 + RADEON_READ(RADEON_CONFIG_APER_SIZE); 1540 /* New let's set the memory map ... */
1541 if (dev_priv->new_memmap) {
1542 u32 base = 0;
1543
1544 DRM_INFO("Setting GART location based on new memory map\n");
1545
1546 /* If using AGP, try to locate the AGP aperture at the same
1547 * location in the card and on the bus, though we have to
1548 * align it down.
1549 */
1550#if __OS_HAS_AGP
1551 if (dev_priv->flags & CHIP_IS_AGP) {
1552 base = dev->agp->base;
1553 /* Check if valid */
1554 if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
1555 base < (dev_priv->fb_location + dev_priv->fb_size)) {
1556 DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
1557 dev->agp->base);
1558 base = 0;
1559 }
1560 }
1561#endif
1562 /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
1563 if (base == 0) {
1564 base = dev_priv->fb_location + dev_priv->fb_size;
1565 if (((base + dev_priv->gart_size) & 0xfffffffful)
1566 < base)
1567 base = dev_priv->fb_location
1568 - dev_priv->gart_size;
1569 }
1570 dev_priv->gart_vm_start = base & 0xffc00000u;
1571 if (dev_priv->gart_vm_start != base)
1572 DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
1573 base, dev_priv->gart_vm_start);
1574 } else {
1575 DRM_INFO("Setting GART location based on old memory map\n");
1576 dev_priv->gart_vm_start = dev_priv->fb_location +
1577 RADEON_READ(RADEON_CONFIG_APER_SIZE);
1578 }
1515 1579
1516#if __OS_HAS_AGP 1580#if __OS_HAS_AGP
1517 if (dev_priv->flags & CHIP_IS_AGP) 1581 if (dev_priv->flags & CHIP_IS_AGP)
@@ -1596,6 +1660,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1596 dev_priv->last_buf = 0; 1660 dev_priv->last_buf = 0;
1597 1661
1598 radeon_do_engine_reset(dev); 1662 radeon_do_engine_reset(dev);
1663 radeon_test_writeback(dev_priv);
1599 1664
1600 return 0; 1665 return 0;
1601} 1666}
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 9c177a6b2a4c..c8e279e89c2e 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -222,6 +222,7 @@ typedef union {
222# define R300_WAIT_3D 0x2 222# define R300_WAIT_3D 0x2
223# define R300_WAIT_2D_CLEAN 0x3 223# define R300_WAIT_2D_CLEAN 0x3
224# define R300_WAIT_3D_CLEAN 0x4 224# define R300_WAIT_3D_CLEAN 0x4
225#define R300_CMD_SCRATCH 8
225 226
226typedef union { 227typedef union {
227 unsigned int u; 228 unsigned int u;
@@ -247,6 +248,9 @@ typedef union {
247 struct { 248 struct {
248 unsigned char cmd_type, flags, pad0, pad1; 249 unsigned char cmd_type, flags, pad0, pad1;
249 } wait; 250 } wait;
251 struct {
252 unsigned char cmd_type, reg, n_bufs, flags;
253 } scratch;
250} drm_r300_cmd_header_t; 254} drm_r300_cmd_header_t;
251 255
252#define RADEON_FRONT 0x1 256#define RADEON_FRONT 0x1
@@ -697,6 +701,7 @@ typedef struct drm_radeon_setparam {
697#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ 701#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
698#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ 702#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
699#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ 703#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
704#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
700 705
701/* 1.14: Clients can allocate/free a surface 706/* 1.14: Clients can allocate/free a surface
702 */ 707 */
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 1f7d2ab8c4fc..78345cee8f8e 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
38 38
39#define DRIVER_NAME "radeon" 39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon" 40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20051229" 41#define DRIVER_DATE "20060225"
42 42
43/* Interface history: 43/* Interface history:
44 * 44 *
@@ -91,9 +91,11 @@
91 * 1.20- Add support for r300 texrect 91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam 92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL) 93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
94 */ 96 */
95#define DRIVER_MAJOR 1 97#define DRIVER_MAJOR 1
96#define DRIVER_MINOR 22 98#define DRIVER_MINOR 24
97#define DRIVER_PATCHLEVEL 0 99#define DRIVER_PATCHLEVEL 0
98 100
99/* 101/*
@@ -101,20 +103,21 @@
101 */ 103 */
102enum radeon_family { 104enum radeon_family {
103 CHIP_R100, 105 CHIP_R100,
104 CHIP_RS100,
105 CHIP_RV100, 106 CHIP_RV100,
107 CHIP_RS100,
106 CHIP_RV200, 108 CHIP_RV200,
107 CHIP_R200,
108 CHIP_RS200, 109 CHIP_RS200,
109 CHIP_R250, 110 CHIP_R200,
110 CHIP_RS250,
111 CHIP_RV250, 111 CHIP_RV250,
112 CHIP_RS300,
112 CHIP_RV280, 113 CHIP_RV280,
113 CHIP_R300, 114 CHIP_R300,
114 CHIP_RS300,
115 CHIP_R350, 115 CHIP_R350,
116 CHIP_RV350, 116 CHIP_RV350,
117 CHIP_RV380,
117 CHIP_R420, 118 CHIP_R420,
119 CHIP_RV410,
120 CHIP_RS400,
118 CHIP_LAST, 121 CHIP_LAST,
119}; 122};
120 123
@@ -136,9 +139,11 @@ enum radeon_chip_flags {
136 CHIP_IS_AGP = 0x00080000UL, 139 CHIP_IS_AGP = 0x00080000UL,
137 CHIP_HAS_HIERZ = 0x00100000UL, 140 CHIP_HAS_HIERZ = 0x00100000UL,
138 CHIP_IS_PCIE = 0x00200000UL, 141 CHIP_IS_PCIE = 0x00200000UL,
142 CHIP_NEW_MEMMAP = 0x00400000UL,
139}; 143};
140 144
141#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) 145#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
146 DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
142#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) 147#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
143 148
144typedef struct drm_radeon_freelist { 149typedef struct drm_radeon_freelist {
@@ -199,6 +204,8 @@ typedef struct drm_radeon_private {
199 drm_radeon_sarea_t *sarea_priv; 204 drm_radeon_sarea_t *sarea_priv;
200 205
201 u32 fb_location; 206 u32 fb_location;
207 u32 fb_size;
208 int new_memmap;
202 209
203 int gart_size; 210 int gart_size;
204 u32 gart_vm_start; 211 u32 gart_vm_start;
@@ -272,6 +279,8 @@ typedef struct drm_radeon_private {
272 unsigned long pcigart_offset; 279 unsigned long pcigart_offset;
273 drm_ati_pcigart_info gart_info; 280 drm_ati_pcigart_info gart_info;
274 281
282 u32 scratch_ages[5];
283
275 /* starting from here on, data is preserved accross an open */ 284 /* starting from here on, data is preserved accross an open */
276 uint32_t flags; /* see radeon_chip_flags */ 285 uint32_t flags; /* see radeon_chip_flags */
277} drm_radeon_private_t; 286} drm_radeon_private_t;
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 7bc27516d425..c5b8f774a599 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -45,22 +45,53 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
45 u32 off = *offset; 45 u32 off = *offset;
46 struct drm_radeon_driver_file_fields *radeon_priv; 46 struct drm_radeon_driver_file_fields *radeon_priv;
47 47
48 if (off >= dev_priv->fb_location && 48 /* Hrm ... the story of the offset ... So this function converts
49 off < (dev_priv->gart_vm_start + dev_priv->gart_size)) 49 * the various ideas of what userland clients might have for an
50 return 0; 50 * offset in the card address space into an offset into the card
51 51 * address space :) So with a sane client, it should just keep
52 radeon_priv = filp_priv->driver_priv; 52 * the value intact and just do some boundary checking. However,
53 off += radeon_priv->radeon_fb_delta; 53 * not all clients are sane. Some older clients pass us 0 based
54 * offsets relative to the start of the framebuffer and some may
55 * assume the AGP aperture it appended to the framebuffer, so we
56 * try to detect those cases and fix them up.
57 *
58 * Note: It might be a good idea here to make sure the offset lands
59 * in some "allowed" area to protect things like the PCIE GART...
60 */
54 61
55 DRM_DEBUG("offset fixed up to 0x%x\n", off); 62 /* First, the best case, the offset already lands in either the
63 * framebuffer or the GART mapped space
64 */
65 if ((off >= dev_priv->fb_location &&
66 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
67 (off >= dev_priv->gart_vm_start &&
68 off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
69 return 0;
56 70
57 if (off < dev_priv->fb_location || 71 /* Ok, that didn't happen... now check if we have a zero based
58 off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) 72 * offset that fits in the framebuffer + gart space, apply the
59 return DRM_ERR(EINVAL); 73 * magic offset we get from SETPARAM or calculated from fb_location
74 */
75 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
76 radeon_priv = filp_priv->driver_priv;
77 off += radeon_priv->radeon_fb_delta;
78 }
60 79
61 *offset = off; 80 /* Finally, assume we aimed at a GART offset if beyond the fb */
81 if (off > (dev_priv->fb_location + dev_priv->fb_size))
82 off = off - (dev_priv->fb_location + dev_priv->fb_size) +
83 dev_priv->gart_vm_start;
62 84
63 return 0; 85 /* Now recheck and fail if out of bounds */
86 if ((off >= dev_priv->fb_location &&
87 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
88 (off >= dev_priv->gart_vm_start &&
89 off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
90 DRM_DEBUG("offset fixed up to 0x%x\n", off);
91 *offset = off;
92 return 0;
93 }
94 return DRM_ERR(EINVAL);
64} 95}
65 96
66static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * 97static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
@@ -1939,11 +1970,6 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS)
1939 drm_radeon_private_t *dev_priv = dev->dev_private; 1970 drm_radeon_private_t *dev_priv = dev->dev_private;
1940 drm_radeon_surface_alloc_t alloc; 1971 drm_radeon_surface_alloc_t alloc;
1941 1972
1942 if (!dev_priv) {
1943 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1944 return DRM_ERR(EINVAL);
1945 }
1946
1947 DRM_COPY_FROM_USER_IOCTL(alloc, 1973 DRM_COPY_FROM_USER_IOCTL(alloc,
1948 (drm_radeon_surface_alloc_t __user *) data, 1974 (drm_radeon_surface_alloc_t __user *) data,
1949 sizeof(alloc)); 1975 sizeof(alloc));
@@ -1960,12 +1986,7 @@ static int radeon_surface_free(DRM_IOCTL_ARGS)
1960 drm_radeon_private_t *dev_priv = dev->dev_private; 1986 drm_radeon_private_t *dev_priv = dev->dev_private;
1961 drm_radeon_surface_free_t memfree; 1987 drm_radeon_surface_free_t memfree;
1962 1988
1963 if (!dev_priv) { 1989 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data,
1964 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1965 return DRM_ERR(EINVAL);
1966 }
1967
1968 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
1969 sizeof(memfree)); 1990 sizeof(memfree));
1970 1991
1971 if (free_surface(filp, dev_priv, memfree.address)) 1992 if (free_surface(filp, dev_priv, memfree.address))
@@ -2100,11 +2121,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
2100 2121
2101 LOCK_TEST_WITH_RETURN(dev, filp); 2122 LOCK_TEST_WITH_RETURN(dev, filp);
2102 2123
2103 if (!dev_priv) {
2104 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2105 return DRM_ERR(EINVAL);
2106 }
2107
2108 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2124 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2109 2125
2110 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, 2126 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2189,11 +2205,6 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS)
2189 2205
2190 LOCK_TEST_WITH_RETURN(dev, filp); 2206 LOCK_TEST_WITH_RETURN(dev, filp);
2191 2207
2192 if (!dev_priv) {
2193 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2194 return DRM_ERR(EINVAL);
2195 }
2196
2197 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2208 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2198 2209
2199 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, 2210 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data,
@@ -2340,11 +2351,6 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS)
2340 2351
2341 LOCK_TEST_WITH_RETURN(dev, filp); 2352 LOCK_TEST_WITH_RETURN(dev, filp);
2342 2353
2343 if (!dev_priv) {
2344 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2345 return DRM_ERR(EINVAL);
2346 }
2347
2348 DRM_COPY_FROM_USER_IOCTL(indirect, 2354 DRM_COPY_FROM_USER_IOCTL(indirect,
2349 (drm_radeon_indirect_t __user *) data, 2355 (drm_radeon_indirect_t __user *) data,
2350 sizeof(indirect)); 2356 sizeof(indirect));
@@ -2417,11 +2423,6 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS)
2417 2423
2418 LOCK_TEST_WITH_RETURN(dev, filp); 2424 LOCK_TEST_WITH_RETURN(dev, filp);
2419 2425
2420 if (!dev_priv) {
2421 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2422 return DRM_ERR(EINVAL);
2423 }
2424
2425 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2426 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2426 2427
2427 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, 2428 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data,
@@ -2738,11 +2739,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
2738 2739
2739 LOCK_TEST_WITH_RETURN(dev, filp); 2740 LOCK_TEST_WITH_RETURN(dev, filp);
2740 2741
2741 if (!dev_priv) {
2742 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2743 return DRM_ERR(EINVAL);
2744 }
2745
2746 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2742 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2747 2743
2748 DRM_COPY_FROM_USER_IOCTL(cmdbuf, 2744 DRM_COPY_FROM_USER_IOCTL(cmdbuf,
@@ -2897,11 +2893,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
2897 drm_radeon_getparam_t param; 2893 drm_radeon_getparam_t param;
2898 int value; 2894 int value;
2899 2895
2900 if (!dev_priv) {
2901 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2902 return DRM_ERR(EINVAL);
2903 }
2904
2905 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, 2896 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data,
2906 sizeof(param)); 2897 sizeof(param));
2907 2898
@@ -2981,11 +2972,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
2981 drm_radeon_setparam_t sp; 2972 drm_radeon_setparam_t sp;
2982 struct drm_radeon_driver_file_fields *radeon_priv; 2973 struct drm_radeon_driver_file_fields *radeon_priv;
2983 2974
2984 if (!dev_priv) {
2985 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2986 return DRM_ERR(EINVAL);
2987 }
2988
2989 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2975 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2990 2976
2991 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, 2977 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data,
@@ -3012,6 +2998,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
3012 case RADEON_SETPARAM_PCIGART_LOCATION: 2998 case RADEON_SETPARAM_PCIGART_LOCATION:
3013 dev_priv->pcigart_offset = sp.value; 2999 dev_priv->pcigart_offset = sp.value;
3014 break; 3000 break;
3001 case RADEON_SETPARAM_NEW_MEMMAP:
3002 dev_priv->new_memmap = sp.value;
3003 break;
3015 default: 3004 default:
3016 DRM_DEBUG("Invalid parameter %d\n", sp.param); 3005 DRM_DEBUG("Invalid parameter %d\n", sp.param);
3017 return DRM_ERR(EINVAL); 3006 return DRM_ERR(EINVAL);
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 6774d2fe3452..5e9936bc307f 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
110 110
111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); 111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
112 112
113 DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); 113 DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
114 114
115 return retval; 115 return retval;
116} 116}
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index 6152415644e9..c33d068cde19 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -196,9 +196,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
196{ 196{
197 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 197 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
198 unsigned int cur_irq_sequence; 198 unsigned int cur_irq_sequence;
199 drm_via_irq_t *cur_irq = dev_priv->via_irqs; 199 drm_via_irq_t *cur_irq;
200 int ret = 0; 200 int ret = 0;
201 maskarray_t *masks = dev_priv->irq_masks; 201 maskarray_t *masks;
202 int real_irq; 202 int real_irq;
203 203
204 DRM_DEBUG("%s\n", __FUNCTION__); 204 DRM_DEBUG("%s\n", __FUNCTION__);
@@ -221,8 +221,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
221 __FUNCTION__, irq); 221 __FUNCTION__, irq);
222 return DRM_ERR(EINVAL); 222 return DRM_ERR(EINVAL);
223 } 223 }
224 224
225 cur_irq += real_irq; 225 masks = dev_priv->irq_masks;
226 cur_irq = dev_priv->via_irqs + real_irq;
226 227
227 if (masks[real_irq][2] && !force_sequence) { 228 if (masks[real_irq][2] && !force_sequence) {
228 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, 229 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
@@ -247,11 +248,12 @@ void via_driver_irq_preinstall(drm_device_t * dev)
247{ 248{
248 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 249 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
249 u32 status; 250 u32 status;
250 drm_via_irq_t *cur_irq = dev_priv->via_irqs; 251 drm_via_irq_t *cur_irq;
251 int i; 252 int i;
252 253
253 DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); 254 DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
254 if (dev_priv) { 255 if (dev_priv) {
256 cur_irq = dev_priv->via_irqs;
255 257
256 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; 258 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
257 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; 259 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;