forked from luck/tmp_suning_uos_patched
Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6: drm: Allow for 44 bit user-tokens (or drm_file offsets) drm/via: Disable AGP DMA for chips with the new 3D engine. drm: update core memory manager from git drm tree drm: remove drm_ioremap and drm_ioremapfree i810/i830: use drm_core_ioremap instead of drm_ioremap drm: use vmalloc_user instead of vmalloc_32 for DRM_SHM via: allow for npot texture pitch alignment via: add some new chipsets via: some PCI posting flushes
This commit is contained in:
commit
0c0e8caf9f
@ -532,11 +532,13 @@ typedef struct drm_mm_node {
|
||||
int free;
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
struct drm_mm *mm;
|
||||
void *private;
|
||||
} drm_mm_node_t;
|
||||
|
||||
typedef struct drm_mm {
|
||||
drm_mm_node_t root_node;
|
||||
struct list_head fl_entry;
|
||||
struct list_head ml_entry;
|
||||
} drm_mm_t;
|
||||
|
||||
/**
|
||||
@ -843,9 +845,6 @@ extern void drm_mem_init(void);
|
||||
extern int drm_mem_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
|
||||
extern void *drm_ioremap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev);
|
||||
extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
|
||||
|
||||
extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
|
||||
extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
|
||||
@ -1053,33 +1052,18 @@ extern void drm_sysfs_device_remove(struct class_device *class_dev);
|
||||
extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
|
||||
unsigned long size,
|
||||
unsigned alignment);
|
||||
extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur);
|
||||
void drm_mm_put_block(drm_mm_node_t * cur);
|
||||
extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size,
|
||||
unsigned alignment, int best_match);
|
||||
extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size);
|
||||
extern void drm_mm_takedown(drm_mm_t *mm);
|
||||
extern int drm_mm_clean(drm_mm_t *mm);
|
||||
extern unsigned long drm_mm_tail_space(drm_mm_t *mm);
|
||||
extern int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size);
|
||||
extern int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size);
|
||||
|
||||
/* Inline replacements for DRM_IOREMAP macros */
|
||||
static __inline__ void drm_core_ioremap(struct drm_map *map,
|
||||
struct drm_device *dev)
|
||||
{
|
||||
map->handle = drm_ioremap(map->offset, map->size, dev);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
|
||||
struct drm_device *dev)
|
||||
{
|
||||
map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static __inline__ void drm_core_ioremapfree(struct drm_map *map,
|
||||
struct drm_device *dev)
|
||||
{
|
||||
if (map->handle && map->size)
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
}
|
||||
extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
|
||||
extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
|
||||
|
||||
static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
|
||||
unsigned int token)
|
||||
|
@ -79,14 +79,14 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
|
||||
|
||||
if (!use_hashed_handle) {
|
||||
int ret;
|
||||
hash->key = user_token;
|
||||
hash->key = user_token >> PAGE_SHIFT;
|
||||
ret = drm_ht_insert_item(&dev->map_hash, hash);
|
||||
if (ret != -EINVAL)
|
||||
return ret;
|
||||
}
|
||||
return drm_ht_just_insert_please(&dev->map_hash, hash,
|
||||
user_token, 32 - PAGE_SHIFT - 3,
|
||||
PAGE_SHIFT, DRM_MAP_HASH_OFFSET);
|
||||
0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,11 +178,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
||||
}
|
||||
}
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
map->handle = drm_ioremap(map->offset, map->size, dev);
|
||||
map->handle = ioremap(map->offset, map->size);
|
||||
break;
|
||||
|
||||
case _DRM_SHM:
|
||||
map->handle = vmalloc_32(map->size);
|
||||
map->handle = vmalloc_user(map->size);
|
||||
DRM_DEBUG("%lu %d %p\n",
|
||||
map->size, drm_order(map->size), map->handle);
|
||||
if (!map->handle) {
|
||||
@ -238,7 +238,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
||||
list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
|
||||
if (!list) {
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
iounmap(map->handle);
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
||||
ret = drm_map_handle(dev, &list->hash, user_token, 0);
|
||||
if (ret) {
|
||||
if (map->type == _DRM_REGISTERS)
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
iounmap(map->handle);
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
list->user_token = list->hash.key;
|
||||
list->user_token = list->hash.key << PAGE_SHIFT;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
*maplist = list;
|
||||
@ -347,7 +347,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
||||
|
||||
if (r_list->map == map) {
|
||||
list_del(list);
|
||||
drm_ht_remove_key(&dev->map_hash, r_list->user_token);
|
||||
drm_ht_remove_key(&dev->map_hash,
|
||||
r_list->user_token >> PAGE_SHIFT);
|
||||
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
||||
break;
|
||||
}
|
||||
@ -362,7 +363,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
iounmap(map->handle);
|
||||
/* FALLTHROUGH */
|
||||
case _DRM_FRAME_BUFFER:
|
||||
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
|
||||
|
@ -79,28 +79,6 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
}
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
/*
|
||||
* Find the drm_map that covers the range [offset, offset+size).
|
||||
*/
|
||||
static drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
drm_map_t *map;
|
||||
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
map = r_list->map;
|
||||
if (!map)
|
||||
continue;
|
||||
if (map->offset <= offset
|
||||
&& (offset + size) <= (map->offset + map->size))
|
||||
return map;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
@ -169,13 +147,6 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
|
||||
}
|
||||
|
||||
#else /* __OS_HAS_AGP */
|
||||
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
@ -184,57 +155,28 @@ static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
|
||||
#endif /* agp */
|
||||
|
||||
void *drm_ioremap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
|
||||
if (map && map->type == _DRM_AGP)
|
||||
return agp_remap(offset, size, dev);
|
||||
}
|
||||
return ioremap(offset, size);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ioremap);
|
||||
|
||||
#if 0
|
||||
void *drm_ioremap_nocache(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
|
||||
if (map && map->type == _DRM_AGP)
|
||||
return agp_remap(offset, size, dev);
|
||||
}
|
||||
return ioremap_nocache(offset, size);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void drm_ioremapfree(void *pt, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
/*
|
||||
* This is a bit ugly. It would be much cleaner if the DRM API would use separate
|
||||
* routines for handling mappings in the AGP space. Hopefully this can be done in
|
||||
* a future revision of the interface...
|
||||
*/
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
|
||||
&& ((unsigned long)pt >= VMALLOC_START
|
||||
&& (unsigned long)pt < VMALLOC_END)) {
|
||||
unsigned long offset;
|
||||
drm_map_t *map;
|
||||
|
||||
offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
|
||||
map = drm_lookup_map(offset, size, dev);
|
||||
if (map && map->type == _DRM_AGP) {
|
||||
vunmap(pt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
iounmap(pt);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ioremapfree);
|
||||
|
||||
#endif /* debug_memory */
|
||||
|
||||
void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) &&
|
||||
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
|
||||
map->handle = agp_remap(map->offset, map->size, dev);
|
||||
else
|
||||
map->handle = ioremap(map->offset, map->size);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_core_ioremap);
|
||||
|
||||
void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
|
||||
{
|
||||
if (!map->handle || !map->size)
|
||||
return;
|
||||
|
||||
if (drm_core_has_AGP(dev) &&
|
||||
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
|
||||
vunmap(map->handle);
|
||||
else
|
||||
iounmap(map->handle);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_core_ioremapfree);
|
||||
|
||||
|
@ -56,26 +56,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
|
||||
pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
|
||||
pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
|
||||
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
|
||||
return pte_pfn(*ptep) << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#else /* __OS_HAS_AGP */
|
||||
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *drm_ioremap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev);
|
||||
|
||||
void drm_ioremapfree(void *pt, unsigned long size,
|
||||
drm_device_t * dev);
|
||||
|
@ -205,76 +205,6 @@ void drm_free (void *pt, size_t size, int area) {
|
||||
}
|
||||
}
|
||||
|
||||
void *drm_ioremap (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Mapping 0 bytes at 0x%08lx\n", offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pt = drm_ioremap(offset, size, dev))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
return pt;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Mapping 0 bytes at 0x%08lx\n", offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
return NULL;
|
||||
}
|
||||
spin_lock(&drm_mem_lock);
|
||||
++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
return pt;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
|
||||
if (!pt)
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Attempt to free NULL pointer\n");
|
||||
else
|
||||
drm_ioremapfree(pt, size, dev);
|
||||
|
||||
spin_lock(&drm_mem_lock);
|
||||
drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
"Excess frees: %d frees, %d allocs\n",
|
||||
free_count, alloc_count);
|
||||
}
|
||||
}
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
|
||||
DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
|
||||
|
@ -42,36 +42,131 @@
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include <linux/slab.h>
|
||||
|
||||
unsigned long drm_mm_tail_space(drm_mm_t *mm)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
drm_mm_node_t *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
|
||||
if (!entry->free)
|
||||
return 0;
|
||||
|
||||
return entry->size;
|
||||
}
|
||||
|
||||
int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
drm_mm_node_t *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
|
||||
if (!entry->free)
|
||||
return -ENOMEM;
|
||||
|
||||
if (entry->size <= size)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->size -= size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int drm_mm_create_tail_node(drm_mm_t *mm,
|
||||
unsigned long start,
|
||||
unsigned long size)
|
||||
{
|
||||
drm_mm_node_t *child;
|
||||
|
||||
child = (drm_mm_node_t *)
|
||||
drm_alloc(sizeof(*child), DRM_MEM_MM);
|
||||
if (!child)
|
||||
return -ENOMEM;
|
||||
|
||||
child->free = 1;
|
||||
child->size = size;
|
||||
child->start = start;
|
||||
child->mm = mm;
|
||||
|
||||
list_add_tail(&child->ml_entry, &mm->ml_entry);
|
||||
list_add_tail(&child->fl_entry, &mm->fl_entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size)
|
||||
{
|
||||
struct list_head *tail_node;
|
||||
drm_mm_node_t *entry;
|
||||
|
||||
tail_node = mm->ml_entry.prev;
|
||||
entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
|
||||
if (!entry->free) {
|
||||
return drm_mm_create_tail_node(mm, entry->start + entry->size, size);
|
||||
}
|
||||
entry->size += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent,
|
||||
unsigned long size)
|
||||
{
|
||||
drm_mm_node_t *child;
|
||||
|
||||
child = (drm_mm_node_t *)
|
||||
drm_alloc(sizeof(*child), DRM_MEM_MM);
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
child->free = 0;
|
||||
child->size = size;
|
||||
child->start = parent->start;
|
||||
child->mm = parent->mm;
|
||||
|
||||
list_add_tail(&child->ml_entry, &parent->ml_entry);
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
parent->size -= size;
|
||||
parent->start += size;
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
|
||||
drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
|
||||
unsigned long size, unsigned alignment)
|
||||
{
|
||||
|
||||
drm_mm_node_t *align_splitoff = NULL;
|
||||
drm_mm_node_t *child;
|
||||
unsigned tmp = 0;
|
||||
|
||||
if (alignment)
|
||||
size += alignment - 1;
|
||||
tmp = parent->start % alignment;
|
||||
|
||||
if (tmp) {
|
||||
align_splitoff = drm_mm_split_at_start(parent, alignment - tmp);
|
||||
if (!align_splitoff)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent->size == size) {
|
||||
list_del_init(&parent->fl_entry);
|
||||
parent->free = 0;
|
||||
return parent;
|
||||
} else {
|
||||
child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM);
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&child->ml_entry);
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
child->free = 0;
|
||||
child->size = size;
|
||||
child->start = parent->start;
|
||||
|
||||
list_add_tail(&child->ml_entry, &parent->ml_entry);
|
||||
parent->size -= size;
|
||||
parent->start += size;
|
||||
child = drm_mm_split_at_start(parent, size);
|
||||
}
|
||||
|
||||
if (align_splitoff)
|
||||
drm_mm_put_block(align_splitoff);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
@ -80,12 +175,12 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
|
||||
* Otherwise add to the free stack.
|
||||
*/
|
||||
|
||||
void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur)
|
||||
void drm_mm_put_block(drm_mm_node_t * cur)
|
||||
{
|
||||
|
||||
drm_mm_node_t *list_root = &mm->root_node;
|
||||
drm_mm_t *mm = cur->mm;
|
||||
struct list_head *cur_head = &cur->ml_entry;
|
||||
struct list_head *root_head = &list_root->ml_entry;
|
||||
struct list_head *root_head = &mm->ml_entry;
|
||||
drm_mm_node_t *prev_node = NULL;
|
||||
drm_mm_node_t *next_node;
|
||||
|
||||
@ -116,7 +211,7 @@ void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur)
|
||||
}
|
||||
if (!merged) {
|
||||
cur->free = 1;
|
||||
list_add(&cur->fl_entry, &list_root->fl_entry);
|
||||
list_add(&cur->fl_entry, &mm->fl_entry);
|
||||
} else {
|
||||
list_del(&cur->ml_entry);
|
||||
drm_free(cur, sizeof(*cur), DRM_MEM_MM);
|
||||
@ -128,20 +223,30 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
|
||||
unsigned alignment, int best_match)
|
||||
{
|
||||
struct list_head *list;
|
||||
const struct list_head *free_stack = &mm->root_node.fl_entry;
|
||||
const struct list_head *free_stack = &mm->fl_entry;
|
||||
drm_mm_node_t *entry;
|
||||
drm_mm_node_t *best;
|
||||
unsigned long best_size;
|
||||
unsigned wasted;
|
||||
|
||||
best = NULL;
|
||||
best_size = ~0UL;
|
||||
|
||||
if (alignment)
|
||||
size += alignment - 1;
|
||||
|
||||
list_for_each(list, free_stack) {
|
||||
entry = list_entry(list, drm_mm_node_t, fl_entry);
|
||||
if (entry->size >= size) {
|
||||
wasted = 0;
|
||||
|
||||
if (entry->size < size)
|
||||
continue;
|
||||
|
||||
if (alignment) {
|
||||
register unsigned tmp = entry->start % alignment;
|
||||
if (tmp)
|
||||
wasted += alignment - tmp;
|
||||
}
|
||||
|
||||
|
||||
if (entry->size >= size + wasted) {
|
||||
if (!best_match)
|
||||
return entry;
|
||||
if (size < best_size) {
|
||||
@ -154,40 +259,32 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
|
||||
return best;
|
||||
}
|
||||
|
||||
int drm_mm_clean(drm_mm_t * mm)
|
||||
{
|
||||
struct list_head *head = &mm->ml_entry;
|
||||
|
||||
return (head->next->next == head);
|
||||
}
|
||||
|
||||
int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
|
||||
{
|
||||
drm_mm_node_t *child;
|
||||
INIT_LIST_HEAD(&mm->ml_entry);
|
||||
INIT_LIST_HEAD(&mm->fl_entry);
|
||||
|
||||
INIT_LIST_HEAD(&mm->root_node.ml_entry);
|
||||
INIT_LIST_HEAD(&mm->root_node.fl_entry);
|
||||
child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM);
|
||||
if (!child)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&child->ml_entry);
|
||||
INIT_LIST_HEAD(&child->fl_entry);
|
||||
|
||||
child->start = start;
|
||||
child->size = size;
|
||||
child->free = 1;
|
||||
|
||||
list_add(&child->fl_entry, &mm->root_node.fl_entry);
|
||||
list_add(&child->ml_entry, &mm->root_node.ml_entry);
|
||||
|
||||
return 0;
|
||||
return drm_mm_create_tail_node(mm, start, size);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_mm_init);
|
||||
|
||||
void drm_mm_takedown(drm_mm_t * mm)
|
||||
{
|
||||
struct list_head *bnode = mm->root_node.fl_entry.next;
|
||||
struct list_head *bnode = mm->fl_entry.next;
|
||||
drm_mm_node_t *entry;
|
||||
|
||||
entry = list_entry(bnode, drm_mm_node_t, fl_entry);
|
||||
|
||||
if (entry->ml_entry.next != &mm->root_node.ml_entry ||
|
||||
entry->fl_entry.next != &mm->root_node.fl_entry) {
|
||||
if (entry->ml_entry.next != &mm->ml_entry ||
|
||||
entry->fl_entry.next != &mm->fl_entry) {
|
||||
DRM_ERROR("Memory manager not clean. Delaying takedown\n");
|
||||
return;
|
||||
}
|
||||
|
@ -226,12 +226,14 @@
|
||||
{0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
|
||||
{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
|
||||
{0, 0, 0}
|
||||
|
||||
#define i810_PCI_IDS \
|
||||
|
@ -500,7 +500,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
|
||||
for (pt = dev->vmalist; pt; pt = pt->next) {
|
||||
if (!(vma = pt->vma))
|
||||
continue;
|
||||
DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
|
||||
DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
|
||||
pt->pid,
|
||||
vma->vm_start,
|
||||
vma->vm_end,
|
||||
@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
|
||||
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
|
||||
vma->vm_flags & VM_LOCKED ? 'l' : '-',
|
||||
vma->vm_flags & VM_IO ? 'i' : '-',
|
||||
vma->vm_pgoff << PAGE_SHIFT);
|
||||
vma->vm_pgoff);
|
||||
|
||||
#if defined(__i386__)
|
||||
pgprot = pgprot_val(vma->vm_page_prot);
|
||||
|
@ -101,10 +101,9 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size,
|
||||
|
||||
static void drm_sman_mm_free(void *private, void *ref)
|
||||
{
|
||||
drm_mm_t *mm = (drm_mm_t *) private;
|
||||
drm_mm_node_t *node = (drm_mm_node_t *) ref;
|
||||
|
||||
drm_mm_put_block(mm, node);
|
||||
drm_mm_put_block(node);
|
||||
}
|
||||
|
||||
static void drm_sman_mm_destroy(void *private)
|
||||
|
@ -70,7 +70,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
|
||||
if (!dev->agp || !dev->agp->cant_use_aperture)
|
||||
goto vm_nopage_error;
|
||||
|
||||
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash))
|
||||
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
|
||||
goto vm_nopage_error;
|
||||
|
||||
r_list = drm_hash_entry(hash, drm_map_list_t, hash);
|
||||
@ -227,7 +227,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
drm_ioremapfree(map->handle, map->size, dev);
|
||||
iounmap(map->handle);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
vfree(map->handle);
|
||||
@ -463,8 +463,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
|
||||
lock_kernel();
|
||||
dev = priv->head->dev;
|
||||
dma = dev->dma;
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, vma->vm_pgoff);
|
||||
|
||||
/* Length must match exact page count */
|
||||
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
|
||||
@ -537,8 +537,8 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
unsigned long offset = 0;
|
||||
drm_hash_item_t *hash;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT);
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, vma->vm_pgoff);
|
||||
|
||||
if (!priv->authenticated)
|
||||
return -EACCES;
|
||||
@ -547,7 +547,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
* the AGP mapped at physical address 0
|
||||
* --BenH.
|
||||
*/
|
||||
if (!(vma->vm_pgoff << PAGE_SHIFT)
|
||||
if (!vma->vm_pgoff
|
||||
#if __OS_HAS_AGP
|
||||
&& (!dev->agp
|
||||
|| dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
|
||||
@ -555,7 +555,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
)
|
||||
return drm_mmap_dma(filp, vma);
|
||||
|
||||
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) {
|
||||
if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) {
|
||||
DRM_ERROR("Could not find map\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -219,8 +219,7 @@ static int i810_dma_cleanup(drm_device_t * dev)
|
||||
(drm_i810_private_t *) dev->dev_private;
|
||||
|
||||
if (dev_priv->ring.virtual_start) {
|
||||
drm_ioremapfree((void *)dev_priv->ring.virtual_start,
|
||||
dev_priv->ring.Size, dev);
|
||||
drm_core_ioremapfree(&dev_priv->ring.map, dev);
|
||||
}
|
||||
if (dev_priv->hw_status_page) {
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
@ -236,9 +235,9 @@ static int i810_dma_cleanup(drm_device_t * dev)
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[i];
|
||||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
||||
if (buf_priv->kernel_virtual && buf->total)
|
||||
drm_ioremapfree(buf_priv->kernel_virtual,
|
||||
buf->total, dev);
|
||||
drm_core_ioremapfree(&buf_priv->map, dev);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -311,8 +310,15 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
|
||||
|
||||
*buf_priv->in_use = I810_BUF_FREE;
|
||||
|
||||
buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
|
||||
buf->total, dev);
|
||||
buf_priv->map.offset = buf->bus_address;
|
||||
buf_priv->map.size = buf->total;
|
||||
buf_priv->map.type = _DRM_AGP;
|
||||
buf_priv->map.flags = 0;
|
||||
buf_priv->map.mtrr = 0;
|
||||
|
||||
drm_core_ioremap(&buf_priv->map, dev);
|
||||
buf_priv->kernel_virtual = buf_priv->map.handle;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -363,18 +369,24 @@ static int i810_dma_initialize(drm_device_t * dev,
|
||||
dev_priv->ring.End = init->ring_end;
|
||||
dev_priv->ring.Size = init->ring_size;
|
||||
|
||||
dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
|
||||
init->ring_start,
|
||||
init->ring_size, dev);
|
||||
dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
|
||||
dev_priv->ring.map.size = init->ring_size;
|
||||
dev_priv->ring.map.type = _DRM_AGP;
|
||||
dev_priv->ring.map.flags = 0;
|
||||
dev_priv->ring.map.mtrr = 0;
|
||||
|
||||
if (dev_priv->ring.virtual_start == NULL) {
|
||||
drm_core_ioremap(&dev_priv->ring.map, dev);
|
||||
|
||||
if (dev_priv->ring.map.handle == NULL) {
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
i810_dma_cleanup(dev);
|
||||
DRM_ERROR("can not ioremap virtual address for"
|
||||
" ring buffer\n");
|
||||
return -ENOMEM;
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
|
||||
|
||||
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
|
||||
|
||||
dev_priv->w = init->w;
|
||||
|
@ -61,6 +61,7 @@ typedef struct drm_i810_buf_priv {
|
||||
int currently_mapped;
|
||||
void *virtual;
|
||||
void *kernel_virtual;
|
||||
drm_local_map_t map;
|
||||
} drm_i810_buf_priv_t;
|
||||
|
||||
typedef struct _drm_i810_ring_buffer {
|
||||
@ -72,6 +73,7 @@ typedef struct _drm_i810_ring_buffer {
|
||||
int head;
|
||||
int tail;
|
||||
int space;
|
||||
drm_local_map_t map;
|
||||
} drm_i810_ring_buffer_t;
|
||||
|
||||
typedef struct drm_i810_private {
|
||||
|
@ -223,8 +223,7 @@ static int i830_dma_cleanup(drm_device_t * dev)
|
||||
(drm_i830_private_t *) dev->dev_private;
|
||||
|
||||
if (dev_priv->ring.virtual_start) {
|
||||
drm_ioremapfree((void *)dev_priv->ring.virtual_start,
|
||||
dev_priv->ring.Size, dev);
|
||||
drm_core_ioremapfree(&dev_priv->ring.map, dev);
|
||||
}
|
||||
if (dev_priv->hw_status_page) {
|
||||
pci_free_consistent(dev->pdev, PAGE_SIZE,
|
||||
@ -242,8 +241,7 @@ static int i830_dma_cleanup(drm_device_t * dev)
|
||||
drm_buf_t *buf = dma->buflist[i];
|
||||
drm_i830_buf_priv_t *buf_priv = buf->dev_private;
|
||||
if (buf_priv->kernel_virtual && buf->total)
|
||||
drm_ioremapfree(buf_priv->kernel_virtual,
|
||||
buf->total, dev);
|
||||
drm_core_ioremapfree(&buf_priv->map, dev);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -320,8 +318,14 @@ static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv)
|
||||
|
||||
*buf_priv->in_use = I830_BUF_FREE;
|
||||
|
||||
buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
|
||||
buf->total, dev);
|
||||
buf_priv->map.offset = buf->bus_address;
|
||||
buf_priv->map.size = buf->total;
|
||||
buf_priv->map.type = _DRM_AGP;
|
||||
buf_priv->map.flags = 0;
|
||||
buf_priv->map.mtrr = 0;
|
||||
|
||||
drm_core_ioremap(&buf_priv->map, dev);
|
||||
buf_priv->kernel_virtual = buf_priv->map.handle;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -373,18 +377,24 @@ static int i830_dma_initialize(drm_device_t * dev,
|
||||
dev_priv->ring.End = init->ring_end;
|
||||
dev_priv->ring.Size = init->ring_size;
|
||||
|
||||
dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
|
||||
init->ring_start,
|
||||
init->ring_size, dev);
|
||||
dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
|
||||
dev_priv->ring.map.size = init->ring_size;
|
||||
dev_priv->ring.map.type = _DRM_AGP;
|
||||
dev_priv->ring.map.flags = 0;
|
||||
dev_priv->ring.map.mtrr = 0;
|
||||
|
||||
if (dev_priv->ring.virtual_start == NULL) {
|
||||
drm_core_ioremap(&dev_priv->ring.map, dev);
|
||||
|
||||
if (dev_priv->ring.map.handle == NULL) {
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
i830_dma_cleanup(dev);
|
||||
DRM_ERROR("can not ioremap virtual address for"
|
||||
" ring buffer\n");
|
||||
return -ENOMEM;
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
|
||||
|
||||
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
|
||||
|
||||
dev_priv->w = init->w;
|
||||
|
@ -68,6 +68,7 @@ typedef struct drm_i830_buf_priv {
|
||||
int currently_mapped;
|
||||
void __user *virtual;
|
||||
void *kernel_virtual;
|
||||
drm_local_map_t map;
|
||||
} drm_i830_buf_priv_t;
|
||||
|
||||
typedef struct _drm_i830_ring_buffer {
|
||||
@ -79,6 +80,7 @@ typedef struct _drm_i830_ring_buffer {
|
||||
int head;
|
||||
int tail;
|
||||
int space;
|
||||
drm_local_map_t map;
|
||||
} drm_i830_ring_buffer_t;
|
||||
|
||||
typedef struct drm_i830_private {
|
||||
|
@ -190,6 +190,11 @@ static int via_initialize(drm_device_t * dev,
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
||||
if (dev_priv->chipset == VIA_DX9_0) {
|
||||
DRM_ERROR("AGP DMA is not supported on this chip\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
dev_priv->ring.map.offset = dev->agp->base + init->offset;
|
||||
dev_priv->ring.map.size = init->size;
|
||||
dev_priv->ring.map.type = 0;
|
||||
@ -480,6 +485,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
|
||||
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
|
||||
VIA_READ(VIA_REG_TRANSPACE);
|
||||
}
|
||||
}
|
||||
return paused;
|
||||
@ -557,8 +563,9 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
|
||||
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
|
||||
|
||||
DRM_WRITEMEMORYBARRIER();
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
|
||||
VIA_READ(VIA_REG_TRANSPACE);
|
||||
}
|
||||
|
||||
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
|
||||
|
@ -218,7 +218,9 @@ via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine)
|
||||
VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
|
||||
VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
|
||||
VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
|
||||
DRM_WRITEMEMORYBARRIER();
|
||||
VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
|
||||
VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -29,10 +29,10 @@
|
||||
|
||||
#define DRIVER_NAME "via"
|
||||
#define DRIVER_DESC "VIA Unichrome / Pro"
|
||||
#define DRIVER_DATE "20060529"
|
||||
#define DRIVER_DATE "20061227"
|
||||
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 10
|
||||
#define DRIVER_MINOR 11
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
#include "via_verifier.h"
|
||||
@ -79,7 +79,7 @@ typedef struct drm_via_private {
|
||||
char pci_buf[VIA_PCI_BUF_SIZE];
|
||||
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
|
||||
uint32_t num_fire_offsets;
|
||||
int pro_group_a;
|
||||
int chipset;
|
||||
drm_via_irq_t via_irqs[VIA_NUM_IRQS];
|
||||
unsigned num_irqs;
|
||||
maskarray_t *irq_masks;
|
||||
@ -96,8 +96,9 @@ typedef struct drm_via_private {
|
||||
} drm_via_private_t;
|
||||
|
||||
enum via_family {
|
||||
VIA_OTHER = 0,
|
||||
VIA_PRO_GROUP_A,
|
||||
VIA_OTHER = 0, /* Baseline */
|
||||
VIA_PRO_GROUP_A, /* Another video engine and DMA commands */
|
||||
VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */
|
||||
};
|
||||
|
||||
/* VIA MMIO register access */
|
||||
|
@ -258,12 +258,16 @@ void via_driver_irq_preinstall(drm_device_t * dev)
|
||||
dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
|
||||
dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
|
||||
|
||||
dev_priv->irq_masks = (dev_priv->pro_group_a) ?
|
||||
via_pro_group_a_irqs : via_unichrome_irqs;
|
||||
dev_priv->num_irqs = (dev_priv->pro_group_a) ?
|
||||
via_num_pro_group_a : via_num_unichrome;
|
||||
dev_priv->irq_map = (dev_priv->pro_group_a) ?
|
||||
via_irqmap_pro_group_a : via_irqmap_unichrome;
|
||||
if (dev_priv->chipset == VIA_PRO_GROUP_A ||
|
||||
dev_priv->chipset == VIA_DX9_0) {
|
||||
dev_priv->irq_masks = via_pro_group_a_irqs;
|
||||
dev_priv->num_irqs = via_num_pro_group_a;
|
||||
dev_priv->irq_map = via_irqmap_pro_group_a;
|
||||
} else {
|
||||
dev_priv->irq_masks = via_unichrome_irqs;
|
||||
dev_priv->num_irqs = via_num_unichrome;
|
||||
dev_priv->irq_map = via_irqmap_unichrome;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev_priv->num_irqs; ++i) {
|
||||
atomic_set(&cur_irq->irq_received, 0);
|
||||
|
@ -106,8 +106,7 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset)
|
||||
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
|
||||
if (chipset == VIA_PRO_GROUP_A)
|
||||
dev_priv->pro_group_a = 1;
|
||||
dev_priv->chipset = chipset;
|
||||
|
||||
ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
|
||||
if (ret) {
|
||||
|
@ -306,6 +306,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
|
||||
unsigned long lo = ~0, hi = 0, tmp;
|
||||
uint32_t *addr, *pitch, *height, tex;
|
||||
unsigned i;
|
||||
int npot;
|
||||
|
||||
if (end > 9)
|
||||
end = 9;
|
||||
@ -316,12 +317,15 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
|
||||
&(cur_seq->t_addr[tex = cur_seq->texture][start]);
|
||||
pitch = &(cur_seq->pitch[tex][start]);
|
||||
height = &(cur_seq->height[tex][start]);
|
||||
|
||||
npot = cur_seq->tex_npot[tex];
|
||||
for (i = start; i <= end; ++i) {
|
||||
tmp = *addr++;
|
||||
if (tmp < lo)
|
||||
lo = tmp;
|
||||
tmp += (*height++ << *pitch++);
|
||||
if (i == 0 && npot)
|
||||
tmp += (*height++ * *pitch++);
|
||||
else
|
||||
tmp += (*height++ << *pitch++);
|
||||
if (tmp > hi)
|
||||
hi = tmp;
|
||||
}
|
||||
@ -443,13 +447,21 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
|
||||
return 0;
|
||||
case check_texture_addr3:
|
||||
cur_seq->unfinished = tex_address;
|
||||
tmp = ((cmd >> 24) - 0x2B);
|
||||
cur_seq->pitch[cur_seq->texture][tmp] =
|
||||
(cmd & 0x00F00000) >> 20;
|
||||
if (!tmp && (cmd & 0x000FFFFF)) {
|
||||
DRM_ERROR
|
||||
("Unimplemented texture level 0 pitch mode.\n");
|
||||
return 2;
|
||||
tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit);
|
||||
if (tmp == 0 &&
|
||||
(cmd & HC_HTXnEnPit_MASK)) {
|
||||
cur_seq->pitch[cur_seq->texture][tmp] =
|
||||
(cmd & HC_HTXnLnPit_MASK);
|
||||
cur_seq->tex_npot[cur_seq->texture] = 1;
|
||||
} else {
|
||||
cur_seq->pitch[cur_seq->texture][tmp] =
|
||||
(cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT;
|
||||
cur_seq->tex_npot[cur_seq->texture] = 0;
|
||||
if (cmd & 0x000FFFFF) {
|
||||
DRM_ERROR
|
||||
("Unimplemented texture level 0 pitch mode.\n");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case check_texture_addr4:
|
||||
@ -961,7 +973,13 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
|
||||
uint32_t cmd;
|
||||
const uint32_t *buf_end = buf + (size >> 2);
|
||||
verifier_state_t state = state_command;
|
||||
int pro_group_a = dev_priv->pro_group_a;
|
||||
int cme_video;
|
||||
int supported_3d;
|
||||
|
||||
cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A ||
|
||||
dev_priv->chipset == VIA_DX9_0);
|
||||
|
||||
supported_3d = dev_priv->chipset != VIA_DX9_0;
|
||||
|
||||
hc_state->dev = dev;
|
||||
hc_state->unfinished = no_sequence;
|
||||
@ -986,17 +1004,21 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
|
||||
state = via_check_vheader6(&buf, buf_end);
|
||||
break;
|
||||
case state_command:
|
||||
if (HALCYON_HEADER2 == (cmd = *buf))
|
||||
if ((HALCYON_HEADER2 == (cmd = *buf)) &&
|
||||
supported_3d)
|
||||
state = state_header2;
|
||||
else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
state = state_header1;
|
||||
else if (pro_group_a
|
||||
else if (cme_video
|
||||
&& (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
|
||||
state = state_vheader5;
|
||||
else if (pro_group_a
|
||||
else if (cme_video
|
||||
&& (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
|
||||
state = state_vheader6;
|
||||
else {
|
||||
else if ((cmd == HALCYON_HEADER2) && !supported_3d) {
|
||||
DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n");
|
||||
state = state_error;
|
||||
} else {
|
||||
DRM_ERROR
|
||||
("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
|
||||
cmd);
|
||||
|
@ -43,6 +43,7 @@ typedef struct {
|
||||
uint32_t tex_level_lo[2];
|
||||
uint32_t tex_level_hi[2];
|
||||
uint32_t tex_palette_size[2];
|
||||
uint32_t tex_npot[2];
|
||||
drm_via_sequence_t unfinished;
|
||||
int agp_texture;
|
||||
int multitex;
|
||||
|
Loading…
Reference in New Issue
Block a user