Merged ati-5-0-0

main
Kevin E Martin 2001-01-05 22:57:55 +00:00
parent 833af23c5d
commit 0994e635b2
21 changed files with 6450 additions and 844 deletions

View File

@ -7,7 +7,7 @@
# The real targets are in the module-list
O_TARGET := drm.o
module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o
module-list := gamma.o tdfx.o r128.o radeon.o ffb.o mga.o i810.o
export-objs := $(patsubst %.o,%_drv.o,$(module-list))
# libs-objs are included in every module so that radical changes to the
@ -38,23 +38,28 @@ ifeq ($(CONFIG_AGP),y)
lib-objs += agpsupport.o
else
ifeq ($(CONFIG_AGP),m)
lib-objs += agpsupport.o
lib-objs += agpsupport.o
endif
endif
gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx_context.o
r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o r128_state.o
ffb-objs := ffb_drv.o ffb_context.o
mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o mga_state.o
i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o
gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx_context.o
r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o \
r128_state.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_context.o radeon_bufs.o \
radeon_state.o
ffb-objs := ffb_drv.o ffb_context.o
mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o \
mga_state.o
i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o
obj-$(CONFIG_DRM_TDFX) += tdfx.o
obj-$(CONFIG_DRM_R128) += r128.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o
obj-$(CONFIG_DRM_TDFX) += tdfx.o
obj-$(CONFIG_DRM_R128) += r128.o
obj-$(CONFIG_DRM_RADEON) += radeon.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
# When linking into the kernel, link the library just once.
@ -96,5 +101,8 @@ i810.o: $(i810-objs) $(lib)
r128.o: $(r128-objs) $(lib)
$(LD) -r -o $@ $(r128-objs) $(lib)
radeon.o: $(radeon-objs) $(lib)
$(LD) -r -o $@ $(radeon-objs) $(lib)
ffb.o: $(ffb-objs) $(lib)
$(LD) -r -o $@ $(ffb-objs) $(lib)

View File

@ -37,10 +37,10 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
#define R128_DATE "20001215"
#define R128_DATE "20010101"
#define R128_MAJOR 2
#define R128_MINOR 1
#define R128_PATCHLEVEL 2
#define R128_PATCHLEVEL 4
static drm_device_t r128_device;
drm_ctx_t r128_res_ctx;
@ -108,20 +108,22 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)]= { r128_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
@ -489,7 +491,17 @@ int r128_release(struct inode *inode, struct file *filp)
lock_kernel();
dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
/* Force the cleanup of page flipping when required */
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
if ( dev_priv->page_flipping ) {
r128_do_cleanup_pageflip( dev );
}
}
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */

702
linux-core/radeon_drv.c Normal file
View File

@ -0,0 +1,702 @@
/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Kevin E. Martin <martin@valinux.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
#include <linux/config.h>
#include "drmP.h"
#include "radeon_drv.h"
#define RADEON_NAME "radeon"
#define RADEON_DESC "ATI Radeon"
#define RADEON_DATE "20010105"
#define RADEON_MAJOR 1
#define RADEON_MINOR 0
#define RADEON_PATCHLEVEL 0
static drm_device_t radeon_device;
drm_ctx_t radeon_res_ctx;
static struct file_operations radeon_fops = {
#if LINUX_VERSION_CODE >= 0x020400
/* This started being used during 2.4.0-test */
owner: THIS_MODULE,
#endif
open: radeon_open,
flush: drm_flush,
release: radeon_release,
ioctl: radeon_ioctl,
mmap: drm_mmap,
read: drm_read,
fasync: drm_fasync,
poll: drm_poll,
};
static struct miscdevice radeon_misc = {
minor: MISC_DYNAMIC_MINOR,
name: RADEON_NAME,
fops: &radeon_fops,
};
static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { radeon_version, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { radeon_addbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { radeon_mapbufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { radeon_addctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { radeon_rmctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { radeon_modctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { radeon_getctx, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { radeon_switchctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { radeon_newctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { radeon_resctx, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { radeon_lock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { radeon_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
};
#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
#ifdef MODULE
static char *radeon = NULL;
#endif
MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("radeon");
MODULE_PARM(radeon, "s");
#ifndef MODULE
/* radeon_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
* routine, drm_parse_drm.
*/
static int __init radeon_options(char *str)
{
drm_parse_options(str);
return 1;
}
__setup("radeon=", radeon_options);
#endif
static int radeon_setup(drm_device_t *dev)
{
int i;
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
dev->buf_use = 0;
atomic_set(&dev->buf_alloc, 0);
drm_dma_setup(dev);
atomic_set(&dev->total_open, 0);
atomic_set(&dev->total_close, 0);
atomic_set(&dev->total_ioctl, 0);
atomic_set(&dev->total_irq, 0);
atomic_set(&dev->total_ctx, 0);
atomic_set(&dev->total_locks, 0);
atomic_set(&dev->total_unlocks, 0);
atomic_set(&dev->total_contends, 0);
atomic_set(&dev->total_sleeps, 0);
for (i = 0; i < DRM_HASH_SIZE; i++) {
dev->magiclist[i].head = NULL;
dev->magiclist[i].tail = NULL;
}
dev->maplist = NULL;
dev->map_count = 0;
dev->vmalist = NULL;
dev->lock.hw_lock = NULL;
init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
dev->queue_slots = 0;
dev->queuelist = NULL;
dev->irq = 0;
dev->context_flag = 0;
dev->interrupt_flag = 0;
dev->dma_flag = 0;
dev->last_context = 0;
dev->last_switch = 0;
dev->last_checked = 0;
init_timer(&dev->timer);
init_waitqueue_head(&dev->context_wait);
dev->ctx_start = 0;
dev->lck_start = 0;
dev->buf_rp = dev->buf;
dev->buf_wp = dev->buf;
dev->buf_end = dev->buf + DRM_BSZ;
dev->buf_async = NULL;
init_waitqueue_head(&dev->buf_readers);
init_waitqueue_head(&dev->buf_writers);
radeon_res_ctx.handle = -1;
DRM_DEBUG("\n");
/* The kernel's context could be created here, but is now created
in drm_dma_enqueue. This is more resource-efficient for
hardware that does not do DMA, but may mean that
drm_select_queue fails between the time the interrupt is
initialized and the time the queues are initialized. */
return 0;
}
static int radeon_takedown(drm_device_t *dev)
{
int i;
drm_magic_entry_t *pt, *next;
drm_map_t *map;
drm_vma_entry_t *vma, *vma_next;
DRM_DEBUG("\n");
down(&dev->struct_sem);
del_timer(&dev->timer);
if (dev->devname) {
drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
dev->devname = NULL;
}
if (dev->unique) {
drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
dev->unique = NULL;
dev->unique_len = 0;
}
/* Clear pid list */
for (i = 0; i < DRM_HASH_SIZE; i++) {
for (pt = dev->magiclist[i].head; pt; pt = next) {
next = pt->next;
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
}
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
/* Clear AGP information */
if (dev->agp) {
drm_agp_mem_t *entry;
drm_agp_mem_t *nexte;
/* Remove AGP resources, but leave dev->agp
intact until radeon_cleanup is called. */
for (entry = dev->agp->memory; entry; entry = nexte) {
nexte = entry->next;
if (entry->bound) drm_unbind_agp(entry->memory);
drm_free_agp(entry->memory, entry->pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
}
dev->agp->memory = NULL;
if (dev->agp->acquired) _drm_agp_release();
dev->agp->acquired = 0;
dev->agp->enabled = 0;
}
#endif
/* Clear vma list (only built for debugging) */
if (dev->vmalist) {
for (vma = dev->vmalist; vma; vma = vma_next) {
vma_next = vma->next;
drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
}
dev->vmalist = NULL;
}
/* Clear map area and mtrr information */
if (dev->maplist) {
for (i = 0; i < dev->map_count; i++) {
map = dev->maplist[i];
switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
#ifdef CONFIG_MTRR
if (map->mtrr >= 0) {
int retcode;
retcode = mtrr_del(map->mtrr,
map->offset,
map->size);
DRM_DEBUG("mtrr_del = %d\n", retcode);
}
#endif
drm_ioremapfree(map->handle, map->size);
break;
case _DRM_SHM:
drm_free_pages((unsigned long)map->handle,
drm_order(map->size)
- PAGE_SHIFT,
DRM_MEM_SAREA);
break;
case _DRM_AGP:
/* Do nothing here, because this is all
handled in the AGP/GART driver. */
break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
drm_free(dev->maplist,
dev->map_count * sizeof(*dev->maplist),
DRM_MEM_MAPS);
dev->maplist = NULL;
dev->map_count = 0;
}
drm_dma_takedown(dev);
dev->queue_count = 0;
if (dev->lock.hw_lock) {
dev->lock.hw_lock = NULL; /* SHM removed */
dev->lock.pid = 0;
wake_up_interruptible(&dev->lock.lock_queue);
}
up(&dev->struct_sem);
return 0;
}
/* radeon_init is called via init_module at module load time, or via
* linux/init/main.c (this is not currently supported). */
static int __init radeon_init(void)
{
int retcode;
drm_device_t *dev = &radeon_device;
DRM_DEBUG("\n");
memset((void *)dev, 0, sizeof(*dev));
dev->count_lock = SPIN_LOCK_UNLOCKED;
sema_init(&dev->struct_sem, 1);
#ifdef MODULE
drm_parse_options(radeon);
#endif
if ((retcode = misc_register(&radeon_misc))) {
DRM_ERROR("Cannot register \"%s\"\n", RADEON_NAME);
return retcode;
}
dev->device = MKDEV(MISC_MAJOR, radeon_misc.minor);
dev->name = RADEON_NAME;
drm_mem_init();
drm_proc_init(dev);
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
dev->agp = drm_agp_init();
if (dev->agp == NULL) {
DRM_ERROR("Cannot initialize agpgart module.\n");
drm_proc_cleanup();
misc_deregister(&radeon_misc);
radeon_takedown(dev);
return -ENOMEM;
}
#ifdef CONFIG_MTRR
dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
dev->agp->agp_info.aper_size*1024*1024,
MTRR_TYPE_WRCOMB,
1);
#endif
#endif
if((retcode = drm_ctxbitmap_init(dev))) {
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
drm_proc_cleanup();
misc_deregister(&radeon_misc);
radeon_takedown(dev);
return retcode;
}
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
RADEON_NAME,
RADEON_MAJOR,
RADEON_MINOR,
RADEON_PATCHLEVEL,
RADEON_DATE,
radeon_misc.minor);
return 0;
}
/* radeon_cleanup is called via cleanup_module at module unload time. */
static void __exit radeon_cleanup(void)
{
drm_device_t *dev = &radeon_device;
DRM_DEBUG("\n");
drm_proc_cleanup();
if (misc_deregister(&radeon_misc)) {
DRM_ERROR("Cannot unload module\n");
} else {
DRM_INFO("Module unloaded\n");
}
drm_ctxbitmap_cleanup(dev);
radeon_takedown(dev);
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (dev->agp) {
drm_agp_uninit();
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
dev->agp = NULL;
}
#endif
}
module_init(radeon_init);
module_exit(radeon_cleanup);
int radeon_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_version_t version;
int len;
if (copy_from_user(&version,
(drm_version_t *)arg,
sizeof(version)))
return -EFAULT;
#define DRM_COPY(name,value) \
len = strlen(value); \
if (len > name##_len) len = name##_len; \
name##_len = strlen(value); \
if (len && name) { \
if (copy_to_user(name, value, len)) \
return -EFAULT; \
}
version.version_major = RADEON_MAJOR;
version.version_minor = RADEON_MINOR;
version.version_patchlevel = RADEON_PATCHLEVEL;
DRM_COPY(version.name, RADEON_NAME);
DRM_COPY(version.date, RADEON_DATE);
DRM_COPY(version.desc, RADEON_DESC);
if (copy_to_user((drm_version_t *)arg,
&version,
sizeof(version)))
return -EFAULT;
return 0;
}
int radeon_open(struct inode *inode, struct file *filp)
{
drm_device_t *dev = &radeon_device;
int retcode = 0;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
#endif
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
spin_unlock(&dev->count_lock);
return radeon_setup(dev);
}
spin_unlock(&dev->count_lock);
}
return retcode;
}
int radeon_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
int retcode = 0;
lock_kernel();
dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
/* Force the cleanup of page flipping when required */
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
if ( dev_priv->page_flipping ) {
radeon_do_cleanup_pageflip( dev );
}
}
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
#endif
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
if (atomic_read(&dev->ioctl_count) || dev->blocked) {
DRM_ERROR("Device busy: %d %d\n",
atomic_read(&dev->ioctl_count),
dev->blocked);
spin_unlock(&dev->count_lock);
unlock_kernel();
return -EBUSY;
}
spin_unlock(&dev->count_lock);
unlock_kernel();
return radeon_takedown(dev);
}
spin_unlock(&dev->count_lock);
}
unlock_kernel();
return retcode;
}
/* radeon_ioctl is called whenever a process performs an ioctl on /dev/drm. */
int radeon_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
int nr = DRM_IOCTL_NR(cmd);
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
int retcode = 0;
drm_ioctl_desc_t *ioctl;
drm_ioctl_t *func;
atomic_inc(&dev->ioctl_count);
atomic_inc(&dev->total_ioctl);
++priv->ioctl_count;
DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
current->pid, cmd, nr, dev->device, priv->authenticated);
if (nr >= RADEON_IOCTL_COUNT) {
retcode = -EINVAL;
} else {
ioctl = &radeon_ioctls[nr];
func = ioctl->func;
if (!func) {
DRM_DEBUG("no function\n");
retcode = -EINVAL;
} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
|| (ioctl->auth_needed && !priv->authenticated)) {
retcode = -EACCES;
} else {
retcode = (func)(inode, filp, cmd, arg);
}
}
atomic_dec(&dev->ioctl_count);
return retcode;
}
int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DECLARE_WAITQUEUE(entry, current);
int ret = 0;
drm_lock_t lock;
#if DRM_DMA_HISTOGRAM
cycles_t start;
dev->lck_start = start = get_cycles();
#endif
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
return -EFAULT;
if (lock.context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
current->pid, lock.context);
return -EINVAL;
}
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
lock.context, current->pid, dev->lock.hw_lock->lock,
lock.flags);
if (lock.context < 0 /* || lock.context >= dev->queue_count */)
return -EINVAL;
if (!ret) {
add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
current->state = TASK_INTERRUPTIBLE;
if (!dev->lock.hw_lock) {
/* Device has been unregistered */
ret = -EINTR;
break;
}
if (drm_lock_take(&dev->lock.hw_lock->lock,
lock.context)) {
dev->lock.pid = current->pid;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->total_locks);
break; /* Got lock */
}
/* Contention */
atomic_inc(&dev->total_sleeps);
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
current->state = TASK_RUNNING;
remove_wait_queue(&dev->lock.lock_queue, &entry);
}
if (!ret) {
sigemptyset(&dev->sigmask);
sigaddset(&dev->sigmask, SIGSTOP);
sigaddset(&dev->sigmask, SIGTSTP);
sigaddset(&dev->sigmask, SIGTTIN);
sigaddset(&dev->sigmask, SIGTTOU);
dev->sigdata.context = lock.context;
dev->sigdata.lock = dev->lock.hw_lock;
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
if (lock.flags & _DRM_LOCK_READY) {
/* Wait for space in DMA/FIFO */
}
if (lock.flags & _DRM_LOCK_QUIESCENT) {
/* Make hardware quiescent */
DRM_DEBUG("not quiescent!\n");
#if 0
radeon_quiescent(dev);
#endif
}
}
#if LINUX_VERSION_CODE < 0x020400
if (lock.context != radeon_res_ctx.handle) {
current->counter = 5;
current->priority = DEF_PRIORITY/4;
}
#endif
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
#endif
return ret;
}
int radeon_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_lock_t lock;
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
return -EFAULT;
if (lock.context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
current->pid, lock.context);
return -EINVAL;
}
DRM_DEBUG("%d frees lock (%d holds)\n",
lock.context,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
atomic_inc(&dev->total_unlocks);
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
atomic_inc(&dev->total_contends);
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
/* FIXME: Try to send data to card here */
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
}
#if LINUX_VERSION_CODE < 0x020400
if (lock.context != radeon_res_ctx.handle) {
current->counter = 5;
current->priority = DEF_PRIORITY;
}
#endif
unblock_all_signals();
return 0;
}

View File

@ -7,7 +7,7 @@
# The real targets are in the module-list
O_TARGET := drm.o
module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o
module-list := gamma.o tdfx.o r128.o radeon.o ffb.o mga.o i810.o
export-objs := $(patsubst %.o,%_drv.o,$(module-list))
# libs-objs are included in every module so that radical changes to the
@ -38,23 +38,28 @@ ifeq ($(CONFIG_AGP),y)
lib-objs += agpsupport.o
else
ifeq ($(CONFIG_AGP),m)
lib-objs += agpsupport.o
lib-objs += agpsupport.o
endif
endif
gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx_context.o
r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o r128_state.o
ffb-objs := ffb_drv.o ffb_context.o
mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o mga_state.o
i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o
gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx_context.o
r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o \
r128_state.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_context.o radeon_bufs.o \
radeon_state.o
ffb-objs := ffb_drv.o ffb_context.o
mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o \
mga_state.o
i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o
obj-$(CONFIG_DRM_TDFX) += tdfx.o
obj-$(CONFIG_DRM_R128) += r128.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o
obj-$(CONFIG_DRM_TDFX) += tdfx.o
obj-$(CONFIG_DRM_R128) += r128.o
obj-$(CONFIG_DRM_RADEON) += radeon.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
# When linking into the kernel, link the library just once.
@ -96,5 +101,8 @@ i810.o: $(i810-objs) $(lib)
r128.o: $(r128-objs) $(lib)
$(LD) -r -o $@ $(r128-objs) $(lib)
radeon.o: $(radeon-objs) $(lib)
$(LD) -r -o $@ $(radeon-objs) $(lib)
ffb.o: $(ffb-objs) $(lib)
$(LD) -r -o $@ $(ffb-objs) $(lib)

View File

@ -47,7 +47,7 @@
# **** End of SMP/MODVERSIONS detection
MODS= gamma.o tdfx.o r128.o
MODS= gamma.o tdfx.o r128.o radeon.o
LIBS= libdrm.a
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
@ -60,9 +60,6 @@ GAMMAHEADERS= gamma_drv.h $(DRMHEADERS)
TDFXOBJS= tdfx_drv.o tdfx_context.o
TDFXHEADERS= tdfx_drv.h $(DRMHEADERS)
R128OBJS= r128_drv.o r128_cce.o r128_bufs.o r128_state.o r128_context.o
R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS)
INC= /usr/include
CFLAGS= -O2 $(WARNINGS)
@ -138,11 +135,18 @@ MODS += i810.o
endif
MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o
MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_context.o mga_state.o
MGAHEADERS= mga_drv.h $(DRMHEADERS)
I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o
I810HEADERS= i810_drv.h $(DRMHEADERS)
R128OBJS= r128_drv.o r128_cce.o r128_bufs.o r128_context.o r128_state.o
R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS)
RADEONOBJS= radeon_drv.o radeon_cp.o radeon_bufs.o radeon_context.o \
radeon_state.o
RADEONHEADERS= radeon_drv.h radeon_drm.h $(DRMHEADERS)
endif
ifeq ($(SIS),1)
@ -203,11 +207,6 @@ tdfx_drv.o: tdfx_drv.c
tdfx.o: $(TDFXOBJS) $(LIBS)
$(LD) -r $^ -o $@
r128_drv.o: r128_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
r128.o: $(R128OBJS) $(LIBS)
$(LD) -r $^ -o $@
sis.o: $(SISOBJS) $(LIBS)
$(LD) -r $^ -o $@
@ -221,6 +220,16 @@ i810_drv.o: i810_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
i810.o: $(I810OBJS) $(LIBS)
$(LD) -r $^ -o $@
r128_drv.o: r128_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
r128.o: $(R128OBJS) $(LIBS)
$(LD) -r $^ -o $@
radeon_drv.o: radeon_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
radeon.o: $(RADEONOBJS) $(LIBS)
$(LD) -r $^ -o $@
endif
.PHONY: ChangeLog
@ -239,10 +248,11 @@ ChangeLog:
$(DRMOBJS): $(DRMHEADERS)
$(GAMMAOBJS): $(GAMMAHEADERS)
$(TDFXOBJS): $(TDFXHEADERS)
$(R128OBJS): $(R128HEADERS)
ifeq ($(AGP),1)
$(MGAOBJS): $(MGAHEADERS)
$(I810OBJS): $(I810HEADERS)
$(R128OBJS): $(R128HEADERS)
$(RADEONOBJS): $(RADEONHEADERS)
endif
clean:

View File

@ -82,6 +82,7 @@ typedef struct drm_clip_rect {
#include "mga_drm.h"
#include "i810_drm.h"
#include "r128_drm.h"
#include "radeon_drm.h"
#ifdef CONFIG_DRM_SIS
#include "sis_drm.h"
#endif
@ -297,100 +298,117 @@ typedef struct drm_agp_info {
unsigned short id_device;
} drm_agp_info_t;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
/* Mga specific ioctls */
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
/* I810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48)
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#ifdef CONFIG_DRM_SIS
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#endif
#endif

View File

@ -36,9 +36,8 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
#define R128_FIFO_DEBUG 0
/* FIXME: Temporary CCE packet buffer */
u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32)));
/* CCE microcode (from ATI) */
static u32 r128_cce_microcode[] = {
@ -86,23 +85,23 @@ static u32 r128_cce_microcode[] = {
};
#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
#define DO_REMAPFREE(_m) \
do { \
if ((_m)->handle && (_m)->size) \
drm_ioremapfree((_m)->handle, (_m)->size); \
#define DO_IOREMAPFREE(_m) \
do { \
if ((_m)->handle && (_m)->size) \
drm_ioremapfree((_m)->handle, (_m)->size); \
} while (0)
#define DO_FIND_MAP(_m, _o) \
do { \
int _i; \
for (_i = 0; _i < dev->map_count; _i++) { \
if (dev->maplist[_i]->offset == _o) { \
_m = dev->maplist[_i]; \
break; \
} \
} \
#define DO_FIND_MAP(_m, _o) \
do { \
int _i; \
for (_i = 0; _i < dev->map_count; _i++) { \
if (dev->maplist[_i]->offset == _o) { \
_m = dev->maplist[_i]; \
break; \
} \
} \
} while (0)
@ -114,7 +113,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
return R128_READ(R128_CLOCK_CNTL_DATA);
}
#if 0
#if R128_FIFO_DEBUG
static void r128_status( drm_r128_private_t *dev_priv )
{
printk( "GUI_STAT = 0x%08x\n",
@ -175,7 +174,7 @@ static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
int i, ret;
ret = r128_do_wait_for_fifo( dev_priv, 64 );
if ( !ret ) return ret;
if ( ret < 0 ) return ret;
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
@ -241,7 +240,7 @@ static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
udelay( 1 );
}
#if 0
#if R128_FIFO_DEBUG
DRM_ERROR( "failed!\n" );
r128_status( dev_priv );
#endif
@ -263,7 +262,7 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv )
}
/* Reset the Concurrent Command Engine. This will not flush any pending
* commangs, so you must wait for the CCE command stream to complete
* commands, so you must wait for the CCE command stream to complete
* before calling this routine.
*/
static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
@ -275,7 +274,7 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
}
/* Stop the Concurrent Command Engine. This will not flush any pending
* commangs, so you must flush the command stream and wait for the CCE
* commands, so you must flush the command stream and wait for the CCE
* to go idle before calling this routine.
*/
static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
@ -395,7 +394,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
}
dev_priv->cce_mode = init->cce_mode;
dev_priv->cce_secure = init->cce_secure;
/* GH: Simple idle check.
*/
@ -481,12 +479,12 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
DO_REMAP( dev_priv->cce_ring );
DO_REMAP( dev_priv->ring_rptr );
DO_REMAP( dev_priv->buffers );
DO_IOREMAP( dev_priv->cce_ring );
DO_IOREMAP( dev_priv->ring_rptr );
DO_IOREMAP( dev_priv->buffers );
#if 0
if ( !dev_priv->is_pci ) {
DO_REMAP( dev_priv->agp_textures );
DO_IOREMAP( dev_priv->agp_textures );
}
#endif
@ -521,12 +519,12 @@ static int r128_do_cleanup_cce( drm_device_t *dev )
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
DO_REMAPFREE( dev_priv->cce_ring );
DO_REMAPFREE( dev_priv->ring_rptr );
DO_REMAPFREE( dev_priv->buffers );
DO_IOREMAPFREE( dev_priv->cce_ring );
DO_IOREMAPFREE( dev_priv->ring_rptr );
DO_IOREMAPFREE( dev_priv->buffers );
#if 0
if ( !dev_priv->is_pci ) {
DO_REMAPFREE( dev_priv->agp_textures );
DO_IOREMAPFREE( dev_priv->agp_textures );
}
#endif
@ -696,6 +694,69 @@ int r128_engine_reset( struct inode *inode, struct file *filp,
}
/* ================================================================
* Fullscreen mode
*/
static int r128_do_init_pageflip( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET );
dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
R128_WRITE( R128_CRTC_OFFSET_CNTL,
dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
return 0;
}
int r128_do_cleanup_pageflip( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset );
R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
dev_priv->page_flipping = 0;
dev_priv->current_page = 0;
return 0;
}
int r128_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_r128_fullscreen_t fs;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) )
return -EFAULT;
switch ( fs.func ) {
case R128_INIT_FULLSCREEN:
return r128_do_init_pageflip( dev );
case R128_CLEANUP_FULLSCREEN:
return r128_do_cleanup_pageflip( dev );
}
return -EINVAL;
}
/* ================================================================
* Freelist management
*/
@ -802,7 +863,7 @@ void r128_freelist_reset( drm_device_t *dev )
/* ================================================================
* CCE packet submission
* CCE command submission
*/
int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
@ -821,6 +882,8 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
udelay( 1 );
}
/* FIXME: This is being ignored... */
DRM_ERROR( "failed!\n" );
return -EBUSY;
}
@ -837,352 +900,6 @@ void r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
ring->space += ring->size;
}
#if 0
static int r128_verify_command( drm_r128_private_t *dev_priv,
u32 cmd, int *size )
{
int writing = 1;
*size = 0;
switch ( cmd & R128_CCE_PACKET_MASK ) {
case R128_CCE_PACKET0:
if ( (cmd & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2) &&
(cmd & R128_CCE_PACKET0_REG_MASK) !=
(R128_PM4_VC_FPU_SETUP >> 2) ) {
writing = 0;
}
*size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
break;
case R128_CCE_PACKET1:
if ( (cmd & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2) &&
(cmd & R128_CCE_PACKET1_REG0_MASK) !=
(R128_PM4_VC_FPU_SETUP >> 2) ) {
writing = 0;
}
if ( (cmd & R128_CCE_PACKET1_REG1_MASK) <= (0x1004 << 9) &&
(cmd & R128_CCE_PACKET1_REG1_MASK) !=
(R128_PM4_VC_FPU_SETUP << 9) ) {
writing = 0;
}
*size = 3;
break;
case R128_CCE_PACKET2:
break;
case R128_CCE_PACKET3:
*size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
break;
}
return writing;
}
static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
u32 *commands, int *count )
{
#if 0
int write = dev_priv->sarea_priv->ring_write;
int *write_ptr = dev_priv->ring_start + write;
int c = *count;
u32 tmp = 0;
int psize = 0;
int writing = 1;
int timeout;
while ( c > 0 ) {
tmp = *commands++;
if ( !psize ) {
writing = r128_verify_command( dev_priv, tmp, &psize );
}
psize--;
if ( writing ) {
write++;
*write_ptr++ = tmp;
}
if ( write >= dev_priv->ring_entries ) {
write = 0;
write_ptr = dev_priv->ring_start;
}
timeout = 0;
while ( write == *dev_priv->ring_read_ptr ) {
R128_READ( R128_PM4_BUFFER_DL_RPTR );
if ( timeout++ >= dev_priv->usec_timeout )
return -EBUSY;
udelay( 1 );
}
c--;
}
if ( write < 32 ) {
memcpy( dev_priv->ring_end,
dev_priv->ring_start,
write * sizeof(u32) );
}
/* Make sure WC cache has been flushed */
r128_flush_write_combine();
dev_priv->sarea_priv->ring_write = write;
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
*count = 0;
#endif
return 0;
}
static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
u32 *commands, int *count )
{
#if 0
int write = dev_priv->sarea_priv->ring_write;
int *write_ptr = dev_priv->ring_start + write;
int c = *count;
int timeout;
while ( c > 0 ) {
write++;
*write_ptr++ = *commands++;
if ( write >= dev_priv->ring_entries ) {
write = 0;
write_ptr = dev_priv->ring_start;
}
timeout = 0;
while ( write == *dev_priv->ring_read_ptr ) {
R128_READ( R128_PM4_BUFFER_DL_RPTR );
if ( timeout++ >= dev_priv->usec_timeout )
return -EBUSY;
udelay( 1 );
}
c--;
}
if ( write < 32 ) {
memcpy( dev_priv->ring_end,
dev_priv->ring_start,
write * sizeof(u32) );
}
/* Make sure WC cache has been flushed */
r128_flush_write_combine();
dev_priv->sarea_priv->ring_write = write;
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
*count = 0;
#endif
return 0;
}
#endif
/* Internal packet submission routine. This uses the insecure versions
* of the packet submission functions, and thus should only be used for
* packets generated inside the kernel module.
*/
int r128_do_submit_packet( drm_r128_private_t *dev_priv,
u32 *buffer, int count )
{
int c = count;
int ret = 0;
#if 0
int left = 0;
if ( c >= dev_priv->ring_entries ) {
c = dev_priv->ring_entries - 1;
left = count - c;
}
/* Since this is only used by the kernel we can use the
* insecure ring buffer submit packet routine.
*/
ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
c += left;
#endif
return ( ret < 0 ) ? ret : c;
}
/* External packet submission routine. This uses the secure versions
* by default, and can thus submit packets received from user space.
*/
int r128_cce_packet( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_packet_t packet;
u32 *buffer;
int c;
int size;
int ret = 0;
#if 0
/* GH: Disable packet submission for now.
*/
return -EINVAL;
#endif
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "r128_submit_packet called without lock held\n" );
return -EINVAL;
}
if ( copy_from_user( &packet, (drm_r128_packet_t *)arg,
sizeof(packet) ) )
return -EFAULT;
#if 0
c = packet.count;
size = c * sizeof(*buffer);
{
int left = 0;
if ( c >= dev_priv->ring_entries ) {
c = dev_priv->ring_entries - 1;
size = c * sizeof(*buffer);
left = packet.count - c;
}
buffer = kmalloc( size, 0 );
if ( buffer == NULL)
return -ENOMEM;
if ( copy_from_user( buffer, packet.buffer, size ) )
return -EFAULT;
if ( dev_priv->cce_secure ) {
ret = r128_submit_packet_ring_secure( dev_priv,
buffer, &c );
} else {
ret = r128_submit_packet_ring_insecure( dev_priv,
buffer, &c );
}
c += left;
}
kfree( buffer );
#else
c = 0;
#endif
packet.count = c;
if ( copy_to_user( (drm_r128_packet_t *)arg, &packet,
sizeof(packet) ) )
return -EFAULT;
if ( ret ) {
return ret;
} else if ( c > 0 ) {
return -EAGAIN;
}
return 0;
}
#if 0
static int r128_send_vertbufs( drm_device_t *dev, drm_r128_vertex_t *v )
{
drm_device_dma_t *dma = dev->dma;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv;
drm_buf_t *buf;
int i, ret;
RING_LOCALS;
/* Make sure we have valid data */
for (i = 0; i < v->send_count; i++) {
int idx = v->send_indices[i];
if (idx < 0 || idx >= dma->buf_count) {
DRM_ERROR("Index %d (of %d max)\n",
idx, dma->buf_count - 1);
return -EINVAL;
}
buf = dma->buflist[idx];
if (buf->pid != current->pid) {
DRM_ERROR("Process %d using buffer owned by %d\n",
current->pid, buf->pid);
return -EINVAL;
}
if (buf->pending) {
DRM_ERROR("Sending pending buffer:"
" buffer %d, offset %d\n",
v->send_indices[i], i);
return -EINVAL;
}
}
/* Wait for idle, if we've wrapped to make sure that all pending
buffers have been processed */
if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
if ((ret = r128_do_cce_idle(dev)) < 0) return ret;
dev_priv->submit_age = 0;
r128_freelist_reset(dev);
}
/* Make sure WC cache has been flushed (if in PIO mode) */
if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
/* FIXME: Add support for sending vertex buffer to the CCE here
instead of in client code. The v->prim holds the primitive
type that should be drawn. Loop over the list buffers in
send_indices[] and submit a packet for each VB.
This will require us to loop over the clip rects here as
well, which implies that we extend the kernel driver to allow
cliprects to be stored here. Note that the cliprects could
possibly come from the X server instead of the client, but
this will require additional changes to the DRI to allow for
this optimization. */
/* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
#if 0
cce_buffer[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
cce_buffer[1] = dev_priv->submit_age;
if ((ret = r128_do_submit_packet(dev, cce_buffer, 2)) < 0) {
/* Until we add support for sending VBs to the CCE in
this routine, we can recover from this error. After
we add that support, we won't be able to easily
recover, so we will probably have to implement
another mechanism for handling timeouts from packets
submitted directly by the kernel. */
return ret;
}
#else
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_VB_AGE_REG, 0 ) );
OUT_RING( dev_priv->submit_age );
ADVANCE_RING();
#endif
/* Now that the submit packet request has succeeded, we can mark
the buffers as pending */
for (i = 0; i < v->send_count; i++) {
buf = dma->buflist[v->send_indices[i]];
buf->pending = 1;
buf_priv = buf->dev_private;
buf_priv->age = dev_priv->submit_age;
}
dev_priv->submit_age++;
return 0;
}
#endif
static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
{
int i;

View File

@ -30,8 +30,8 @@
*
*/
#ifndef _R128_DRM_H_
#define _R128_DRM_H_
#ifndef __R128_DRM_H__
#define __R128_DRM_H__
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (r128_sarea.h)
@ -69,21 +69,13 @@
/* Vertex/indirect buffer size
*/
#if 1
#define R128_BUFFER_SIZE 16384
#else
#define R128_BUFFER_SIZE (128 * 1024)
#endif
/* Byte offsets for indirect buffer data
*/
#define R128_INDEX_PRIM_OFFSET 20
#define R128_HOSTDATA_BLIT_OFFSET 32
/* 2048x2048 @ 32bpp texture requires this many indirect buffers
*/
#define R128_MAX_BLIT_BUFFERS ((2048 * 2048 * 4) / R128_BUFFER_SIZE)
/* Keep these small for testing.
*/
#define R128_NR_SAREA_CLIPRECTS 12
@ -98,7 +90,9 @@
#define R128_LOG_TEX_GRANULARITY 16
#define R128_NR_CONTEXT_REGS 12
#define R128_TEX_MAXLEVELS 11
#define R128_MAX_TEXTURE_LEVELS 11
#define R128_MAX_TEXTURE_UNITS 2
#endif /* __R128_SAREA_DEFINES__ */
@ -137,12 +131,13 @@ typedef struct {
unsigned int scale_3d_cntl;
} drm_r128_context_regs_t;
/* Setup registers for each texture unit */
/* Setup registers for each texture unit
*/
typedef struct {
unsigned int tex_cntl;
unsigned int tex_combine_cntl;
unsigned int tex_size_pitch;
unsigned int tex_offset[R128_TEX_MAXLEVELS];
unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
unsigned int tex_border_color;
} drm_r128_texture_regs_t;
@ -158,7 +153,7 @@ typedef struct drm_r128_sarea {
* on firing a vertex buffer.
*/
drm_r128_context_regs_t context_state;
drm_r128_texture_regs_t tex_state[R128_NR_TEX_HEAPS];
drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS];
unsigned int dirty;
unsigned int vertsize;
unsigned int vc_format;
@ -214,6 +209,13 @@ typedef struct drm_r128_cce_stop {
int idle;
} drm_r128_cce_stop_t;
typedef struct drm_r128_fullscreen {
enum {
R128_INIT_FULLSCREEN = 0x01,
R128_CLEANUP_FULLSCREEN = 0x02
} func;
} drm_r128_fullscreen_t;
typedef struct drm_r128_clear {
unsigned int flags;
int x, y, w, h;
@ -263,10 +265,11 @@ typedef struct drm_r128_stipple {
unsigned int *mask;
} drm_r128_stipple_t;
typedef struct drm_r128_packet {
unsigned int *buffer;
int count;
int flags;
} drm_r128_packet_t;
typedef struct drm_r128_indirect {
int idx;
int start;
int end;
int discard;
} drm_r128_indirect_t;
#endif

View File

@ -37,10 +37,10 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
#define R128_DATE "20001215"
#define R128_DATE "20010101"
#define R128_MAJOR 2
#define R128_MINOR 1
#define R128_PATCHLEVEL 2
#define R128_PATCHLEVEL 4
static drm_device_t r128_device;
drm_ctx_t r128_res_ctx;
@ -108,20 +108,22 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)]= { r128_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
@ -489,7 +491,17 @@ int r128_release(struct inode *inode, struct file *filp)
lock_kernel();
dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
/* Force the cleanup of page flipping when required */
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
if ( dev_priv->page_flipping ) {
r128_do_cleanup_pageflip( dev );
}
}
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */

View File

@ -59,7 +59,6 @@ typedef struct drm_r128_private {
int cce_mode;
int cce_fifo_size;
int cce_secure;
int cce_running;
drm_r128_freelist_t *head;
@ -70,6 +69,11 @@ typedef struct drm_r128_private {
atomic_t idle_count;
int page_flipping;
int current_page;
u32 crtc_offset;
u32 crtc_offset_cntl;
unsigned int fb_bpp;
unsigned int front_offset;
unsigned int front_pitch;
@ -128,7 +132,7 @@ extern int r128_cce_idle( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_engine_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_packet( struct inode *inode, struct file *filp,
extern int r128_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@ -139,6 +143,8 @@ extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
extern void r128_update_ring_snapshot( drm_r128_private_t *dev_priv );
extern int r128_do_cleanup_pageflip( drm_device_t *dev );
/* r128_state.c */
extern int r128_cce_clear( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@ -154,6 +160,8 @@ extern int r128_cce_depth( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_indirect( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* r128_bufs.c */
extern int r128_addbufs(struct inode *inode, struct file *filp,
@ -215,8 +223,10 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CLOCK_CNTL_INDEX 0x0008
#define R128_CLOCK_CNTL_DATA 0x000c
# define R128_PLL_WR_EN (1 << 7)
#define R128_CONSTANT_COLOR_C 0x1d34
#define R128_CRTC_OFFSET 0x0224
#define R128_CRTC_OFFSET_CNTL 0x0228
# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16)
#define R128_DP_GUI_MASTER_CNTL 0x146c
# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
@ -431,12 +441,12 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
n, __FUNCTION__ ); \
(n), __FUNCTION__ ); \
} \
if ( dev_priv->ring.space < n * sizeof(u32) ) { \
r128_wait_ring( dev_priv, n * sizeof(u32) ); \
if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \
r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
dev_priv->ring.space -= n * sizeof(u32); \
dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
tail_mask = dev_priv->ring.tail_mask; \
@ -457,7 +467,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), write ); \
} \
ring[write++] = x; \
ring[write++] = (x); \
write &= tail_mask; \
} while (0)

View File

@ -181,14 +181,14 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 7 + R128_TEX_MAXLEVELS );
BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
2 + R128_TEX_MAXLEVELS ) );
2 + R128_MAX_TEXTURE_LEVELS ) );
OUT_RING( tex->tex_cntl );
OUT_RING( tex->tex_combine_cntl );
OUT_RING( ctx->tex_size_pitch_c );
for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
OUT_RING( tex->tex_offset[i] );
}
@ -207,13 +207,13 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 5 + R128_TEX_MAXLEVELS );
BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
1 + R128_TEX_MAXLEVELS ) );
1 + R128_MAX_TEXTURE_LEVELS ) );
OUT_RING( tex->tex_cntl );
OUT_RING( tex->tex_combine_cntl );
for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
OUT_RING( tex->tex_offset[i] );
}
@ -310,13 +310,13 @@ static void r128_clear_box( drm_r128_private_t *dev_priv,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| fb_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
fb_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS );
OUT_RING( (pitch << 21) | (offset >> 5) );
OUT_RING( color );
@ -398,6 +398,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
return;
}
if ( dev_priv->page_flipping && dev_priv->current_page == 1) {
unsigned int tmp = flags;
flags &= ~(R128_FRONT | R128_BACK);
if ( tmp & R128_FRONT ) flags |= R128_BACK;
if ( tmp & R128_BACK ) flags |= R128_FRONT;
}
for ( i = 0 ; i < nbox ; i++ ) {
int x = pbox[i].x1;
int y = pbox[i].y1;
@ -421,13 +429,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| fb_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
fb_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS );
OUT_RING( dev_priv->front_pitch_offset_c );
OUT_RING( clear_color );
@ -442,13 +450,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| fb_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
fb_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS );
OUT_RING( dev_priv->back_pitch_offset_c );
OUT_RING( clear_color );
@ -463,14 +471,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( clear_depth );
@ -521,16 +529,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| fb_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_NONE |
fb_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_S |
R128_DP_SRC_SOURCE_MEMORY |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->back_pitch_offset_c );
OUT_RING( dev_priv->front_pitch_offset_c );
@ -556,6 +564,48 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
ADVANCE_RING();
}
static void r128_cce_dispatch_flip( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
r128_update_ring_snapshot( dev_priv );
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
*/
r128_cce_performance_boxes( dev_priv );
#endif
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
if ( dev_priv->current_page == 0 ) {
OUT_RING( dev_priv->back_offset );
dev_priv->current_page = 1;
} else {
OUT_RING( dev_priv->front_offset );
dev_priv->current_page = 0;
}
ADVANCE_RING();
/* Increment the frame counter. The client-side 3D driver must
* throttle the framerate by waiting for this value before
* performing the swapbuffer ioctl.
*/
dev_priv->sarea_priv->last_frame++;
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
OUT_RING( dev_priv->sarea_priv->last_frame );
ADVANCE_RING();
}
static void r128_cce_dispatch_vertex( drm_device_t *dev,
drm_buf_t *buf )
{
@ -821,13 +871,17 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
* use a shift instead.
*/
switch ( blit->format ) {
case R128_DATATYPE_ARGB8888:
dword_shift = 0;
break;
case R128_DATATYPE_ARGB1555:
case R128_DATATYPE_RGB565:
case R128_DATATYPE_ARGB4444:
dword_shift = 1;
break;
case R128_DATATYPE_ARGB8888:
dword_shift = 0;
case R128_DATATYPE_CI8:
case R128_DATATYPE_RGB8:
dword_shift = 2;
break;
default:
DRM_ERROR( "invalid blit format %d\n", blit->format );
@ -868,15 +922,15 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| (blit->format << 8)
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_HOST_DATA
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS
| R128_GMC_WR_MSK_DIS );
data[1] = (R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_NONE |
(blit->format << 8) |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_S |
R128_DP_SRC_SOURCE_HOST_DATA |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_AUX_CLIP_DIS |
R128_GMC_WR_MSK_DIS);
data[2] = (blit->pitch << 21) | (blit->offset >> 5);
data[3] = 0xffffffff;
@ -971,15 +1025,14 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
if ( mask[i] ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@ -997,13 +1050,13 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@ -1103,15 +1156,14 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
if ( mask[i] ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@ -1129,13 +1181,13 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_SOLID_COLOR |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_P |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
@ -1188,15 +1240,15 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev,
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_NONE |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_S |
R128_DP_SRC_SOURCE_MEMORY |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
@ -1263,15 +1315,15 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
R128_GMC_DST_PITCH_OFFSET_CNTL |
R128_GMC_BRUSH_NONE |
depth_bpp |
R128_GMC_SRC_DATATYPE_COLOR |
R128_ROP3_S |
R128_DP_SRC_SOURCE_MEMORY |
R128_GMC_CLR_CMP_CNTL_DIS |
R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
@ -1305,7 +1357,7 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
BEGIN_RING( 33 );
OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
for ( i = 0 ; i < 32 ; i++ ) {
OUT_RING( stipple[i] );
}
@ -1370,11 +1422,13 @@ int r128_cce_swap( struct inode *inode, struct file *filp,
if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
r128_cce_dispatch_swap( dev );
/* Make sure we restore the 3D state next time.
*/
dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
if ( !dev_priv->page_flipping ) {
r128_cce_dispatch_swap( dev );
dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
R128_UPLOAD_MASKS);
} else {
r128_cce_dispatch_flip( dev );
}
return 0;
}
@ -1603,3 +1657,20 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
return 0;
}
int r128_cce_indirect( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
/* Indirect buffer firing is not supported at this time.
*/
return -EINVAL;
}

298
linux/radeon_bufs.c Normal file
View File

@ -0,0 +1,298 @@
/* radeon_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Kevin E. Martin <martin@valinux.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
*
*/
#define __NO_VERSION__
#include <linux/config.h>
#include "drmP.h"
#include "radeon_drv.h"
#include "linux/un.h"
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
int radeon_addbufs_agp(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
drm_buf_desc_t request;
drm_buf_entry_t *entry;
drm_buf_t *buf;
unsigned long offset;
unsigned long agp_offset;
int count;
int order;
int size;
int alignment;
int page_order;
int total;
int byte_count;
int i;
if (!dma) return -EINVAL;
if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
return -EFAULT;
count = request.count;
order = drm_order(request.size);
size = 1 << order;
alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;
byte_count = 0;
agp_offset = dev->agp->base + request.agp_start;
DRM_DEBUG("count: %d\n", count);
DRM_DEBUG("order: %d\n", order);
DRM_DEBUG("size: %d\n", size);
DRM_DEBUG("agp_offset: %ld\n", agp_offset);
DRM_DEBUG("alignment: %d\n", alignment);
DRM_DEBUG("page_order: %d\n", page_order);
DRM_DEBUG("total: %d\n", total);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
if (dev->queue_count) return -EBUSY; /* Not while in use */
spin_lock(&dev->count_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
return -EBUSY;
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
down(&dev->struct_sem);
entry = &dma->bufs[order];
if (entry->buf_count) {
up(&dev->struct_sem);
atomic_dec(&dev->buf_alloc);
return -ENOMEM; /* May only call once for each order */
}
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
DRM_MEM_BUFS);
if (!entry->buflist) {
up(&dev->struct_sem);
atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
memset(entry->buflist, 0, count * sizeof(*entry->buflist));
entry->buf_size = size;
entry->page_order = page_order;
offset = 0;
for (offset = 0;
entry->buf_count < count;
offset += alignment, ++entry->buf_count) {
buf = &entry->buflist[entry->buf_count];
buf->idx = dma->buf_count + entry->buf_count;
buf->total = alignment;
buf->order = order;
buf->used = 0;
buf->offset = (dma->byte_count + offset);
buf->address = (void *)(agp_offset + offset);
buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
buf->pid = 0;
buf->dev_priv_size = sizeof(drm_radeon_buf_priv_t);
buf->dev_private = drm_alloc(sizeof(drm_radeon_buf_priv_t),
DRM_MEM_BUFS);
memset(buf->dev_private, 0, buf->dev_priv_size);
#if DRM_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;
buf->time_completed = 0;
buf->time_freed = 0;
#endif
byte_count += PAGE_SIZE << page_order;
DRM_DEBUG("buffer %d @ %p\n",
entry->buf_count, buf->address);
}
DRM_DEBUG("byte_count: %d\n", byte_count);
dma->buflist = drm_realloc(dma->buflist,
dma->buf_count * sizeof(*dma->buflist),
(dma->buf_count + entry->buf_count)
* sizeof(*dma->buflist),
DRM_MEM_BUFS);
for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
dma->buflist[i] = &entry->buflist[i - dma->buf_count];
dma->buf_count += entry->buf_count;
dma->byte_count += byte_count;
drm_freelist_create(&entry->freelist, entry->buf_count);
for (i = 0; i < entry->buf_count; i++) {
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
}
up(&dev->struct_sem);
request.count = entry->buf_count;
request.size = size;
if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request)))
return -EFAULT;
dma->flags = _DRM_DMA_USE_AGP;
atomic_dec(&dev->buf_alloc);
return 0;
}
#endif
int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_buf_desc_t request;
if (!dev_priv || dev_priv->is_pci) return -EINVAL;
if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
return -EFAULT;
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (request.flags & _DRM_AGP_BUFFER)
return radeon_addbufs_agp(inode, filp, cmd, arg);
else
#endif
return -EINVAL;
}
int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
int retcode = 0;
const int zero = 0;
unsigned long virtual;
unsigned long address;
drm_buf_map_t request;
int i;
if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL;
DRM_DEBUG("\n");
spin_lock(&dev->count_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
return -EBUSY;
}
++dev->buf_use; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request)))
return -EFAULT;
if (request.count >= dma->buf_count) {
if (dma->flags & _DRM_DMA_USE_AGP) {
drm_map_t *map;
map = dev_priv->buffers;
if (!map) {
retcode = -EINVAL;
goto done;
}
down(&current->mm->mmap_sem);
virtual = do_mmap(filp, 0, map->size,
PROT_READ|PROT_WRITE,
MAP_SHARED,
(unsigned long)map->offset);
up(&current->mm->mmap_sem);
} else {
down(&current->mm->mmap_sem);
virtual = do_mmap(filp, 0, dma->byte_count,
PROT_READ|PROT_WRITE, MAP_SHARED, 0);
up(&current->mm->mmap_sem);
}
if (virtual > -1024UL) {
/* Real error */
retcode = (signed long)virtual;
goto done;
}
request.virtual = (void *)virtual;
for (i = 0; i < dma->buf_count; i++) {
if (copy_to_user(&request.list[i].idx,
&dma->buflist[i]->idx,
sizeof(request.list[0].idx))) {
retcode = -EFAULT;
goto done;
}
if (copy_to_user(&request.list[i].total,
&dma->buflist[i]->total,
sizeof(request.list[0].total))) {
retcode = -EFAULT;
goto done;
}
if (copy_to_user(&request.list[i].used,
&zero,
sizeof(zero))) {
retcode = -EFAULT;
goto done;
}
address = virtual + dma->buflist[i]->offset;
if (copy_to_user(&request.list[i].address,
&address,
sizeof(address))) {
retcode = -EFAULT;
goto done;
}
}
}
done:
request.count = dma->buf_count;
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request)))
return -EFAULT;
return retcode;
}

215
linux/radeon_context.c Normal file
View File

@ -0,0 +1,215 @@
/* radeon_context.c -- IOCTLs for Radeon contexts -*- linux-c -*-
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Kevin E. Martin <martin@valinux.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
#define __NO_VERSION__
#include "drmP.h"
#include "radeon_drv.h"
extern drm_ctx_t radeon_res_ctx;
static int radeon_alloc_queue(drm_device_t *dev)
{
return drm_ctxbitmap_next(dev);
}
int radeon_context_switch(drm_device_t *dev, int old, int new)
{
char buf[64];
atomic_inc(&dev->total_ctx);
if (test_and_set_bit(0, &dev->context_flag)) {
DRM_ERROR("Reentering -- FIXME\n");
return -EBUSY;
}
#if DRM_DMA_HISTOGRAM
dev->ctx_start = get_cycles();
#endif
DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new == dev->last_context) {
clear_bit(0, &dev->context_flag);
return 0;
}
if (drm_flags & DRM_FLAG_NOCTX) {
radeon_context_switch_complete(dev, new);
} else {
sprintf(buf, "C %d %d\n", old, new);
drm_write_string(dev, buf);
}
return 0;
}
int radeon_context_switch_complete(drm_device_t *dev, int new)
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
dev->last_switch = jiffies;
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("Lock isn't held after context switch\n");
}
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
- dev->ctx_start)]);
#endif
clear_bit(0, &dev->context_flag);
wake_up(&dev->context_wait);
return 0;
}
int radeon_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_res_t res;
drm_ctx_t ctx;
int i;
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
return -EFAULT;
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
return -EFAULT;
return 0;
}
int radeon_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
return -EFAULT;
if ((ctx.handle = radeon_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
ctx.handle = radeon_alloc_queue(dev);
}
DRM_DEBUG("%d\n", ctx.handle);
if (ctx.handle == -1) {
DRM_DEBUG("Not enough free contexts.\n");
/* Should this return -EBUSY instead? */
return -ENOMEM;
}
if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int radeon_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
return -EFAULT;
if (ctx.flags==_DRM_CONTEXT_PRESERVED)
radeon_res_ctx.handle=ctx.handle;
return 0;
}
int radeon_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
return -EFAULT;
/* This is 0, because we don't hanlde any context flags */
ctx.flags = 0;
if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int radeon_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
return radeon_context_switch(dev, dev->last_context, ctx.handle);
}
int radeon_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
radeon_context_switch_complete(dev, ctx.handle);
return 0;
}
int radeon_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
drm_ctxbitmap_free(dev, ctx.handle);
return 0;
}

1314
linux/radeon_cp.c Normal file

File diff suppressed because it is too large Load Diff

325
linux/radeon_drm.h Normal file
View File

@ -0,0 +1,325 @@
/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*-
*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*
*/
#ifndef __RADEON_DRM_H__
#define __RADEON_DRM_H__
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (radeon_sarea.h)
*/
#ifndef __RADEON_SAREA_DEFINES__
#define __RADEON_SAREA_DEFINES__
/* What needs to be changed for the current vertex buffer?
*/
#define RADEON_UPLOAD_CONTEXT 0x00000001
#define RADEON_UPLOAD_VERTFMT 0x00000002
#define RADEON_UPLOAD_LINE 0x00000004
#define RADEON_UPLOAD_BUMPMAP 0x00000008
#define RADEON_UPLOAD_MASKS 0x00000010
#define RADEON_UPLOAD_VIEWPORT 0x00000020
#define RADEON_UPLOAD_SETUP 0x00000040
#define RADEON_UPLOAD_TCL 0x00000080
#define RADEON_UPLOAD_MISC 0x00000100
#define RADEON_UPLOAD_TEX0 0x00000200
#define RADEON_UPLOAD_TEX1 0x00000400
#define RADEON_UPLOAD_TEX2 0x00000800
#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
#define RADEON_UPLOAD_ALL 0x0001ffff
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2
#define RADEON_DEPTH 0x4
/* Primitive types
*/
#define RADEON_POINTS 0x1
#define RADEON_LINES 0x2
#define RADEON_LINE_STRIP 0x3
#define RADEON_TRIANGLES 0x4
#define RADEON_TRIANGLE_FAN 0x5
#define RADEON_TRIANGLE_STRIP 0x6
/* Vertex/indirect buffer size
*/
#define RADEON_BUFFER_SIZE 16384
/* Byte offsets for indirect buffer data
*/
#define RADEON_INDEX_PRIM_OFFSET 20
#define RADEON_HOSTDATA_BLIT_OFFSET 32
#define RADEON_SCRATCH_REG_OFFSET 32
/* Keep these small for testing
*/
#define RADEON_NR_SAREA_CLIPRECTS 12
/* There are 2 heaps (local/AGP). Each region within a heap is a
* minimum of 64k, and there are at most 64 of them per heap.
*/
#define RADEON_LOCAL_TEX_HEAP 0
#define RADEON_AGP_TEX_HEAP 1
#define RADEON_NR_TEX_HEAPS 2
#define RADEON_NR_TEX_REGIONS 64
#define RADEON_LOG_TEX_GRANULARITY 16
#define RADEON_MAX_TEXTURE_LEVELS 11
#define RADEON_MAX_TEXTURE_UNITS 3
#endif /* __RADEON_SAREA_DEFINES__ */
typedef struct {
unsigned int red;
unsigned int green;
unsigned int blue;
unsigned int alpha;
} radeon_color_regs_t;
typedef struct {
/* Context state */
unsigned int pp_misc; /* 0x1c14 */
unsigned int pp_fog_color;
unsigned int re_solid_color;
unsigned int rb3d_blendcntl;
unsigned int rb3d_depthoffset;
unsigned int rb3d_depthpitch;
unsigned int rb3d_zstencilcntl;
unsigned int pp_cntl; /* 0x1c38 */
unsigned int rb3d_cntl;
unsigned int rb3d_coloroffset;
unsigned int re_width_height;
unsigned int rb3d_colorpitch;
unsigned int se_cntl;
/* Vertex format state */
unsigned int se_coord_fmt; /* 0x1c50 */
/* Line state */
unsigned int re_line_pattern; /* 0x1cd0 */
unsigned int re_line_state;
unsigned int se_line_width; /* 0x1db8 */
/* Bumpmap state */
unsigned int pp_lum_matrix; /* 0x1d00 */
unsigned int pp_rot_matrix_0; /* 0x1d58 */
unsigned int pp_rot_matrix_1;
/* Mask state */
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
unsigned int rb3d_ropcntl;
unsigned int rb3d_planemask;
/* Viewport state */
unsigned int se_vport_xscale; /* 0x1d98 */
unsigned int se_vport_xoffset;
unsigned int se_vport_yscale;
unsigned int se_vport_yoffset;
unsigned int se_vport_zscale;
unsigned int se_vport_zoffset;
/* Setup state */
unsigned int se_cntl_status; /* 0x2140 */
#ifdef TCL_ENABLE
/* TCL state */
radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */
radeon_color_regs_t se_tcl_material_ambient;
radeon_color_regs_t se_tcl_material_diffuse;
radeon_color_regs_t se_tcl_material_specular;
unsigned int se_tcl_shininess;
unsigned int se_tcl_output_vtx_fmt;
unsigned int se_tcl_output_vtx_sel;
unsigned int se_tcl_matrix_select_0;
unsigned int se_tcl_matrix_select_1;
unsigned int se_tcl_ucp_vert_blend_ctl;
unsigned int se_tcl_texture_proc_ctl;
unsigned int se_tcl_light_model_ctl;
unsigned int se_tcl_per_light_ctl[4];
#endif
/* Misc state */
unsigned int re_top_left; /* 0x26c0 */
unsigned int re_misc;
} drm_radeon_context_regs_t;
/* Setup registers for each texture unit
*/
typedef struct {
unsigned int pp_txfilter;
unsigned int pp_txformat;
unsigned int pp_txoffset;
unsigned int pp_txcblend;
unsigned int pp_txablend;
unsigned int pp_tfactor;
unsigned int pp_border_color;
#ifdef CUBIC_ENABLE
unsigned int pp_cubic_faces;
unsigned int pp_cubic_offset[5];
#endif
} drm_radeon_texture_regs_t;
typedef struct {
unsigned char next, prev;
unsigned char in_use;
int age;
} drm_radeon_tex_region_t;
typedef struct {
/* The channel for communication of state information to the kernel
* on firing a vertex buffer.
*/
drm_radeon_context_regs_t context_state;
drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
unsigned int dirty;
unsigned int vertsize;
unsigned int vc_format;
/* The current cliprects, or a subset thereof.
*/
drm_clip_rect_t boxes[RADEON_NR_SAREA_CLIPRECTS];
unsigned int nbox;
/* Counters for client-side throttling of rendering clients.
*/
unsigned int last_frame;
unsigned int last_dispatch;
unsigned int last_clear;
drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
int tex_age[RADEON_NR_TEX_HEAPS];
int ctx_owner;
} drm_radeon_sarea_t;
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (xf86drmRadeon.h)
*/
typedef struct drm_radeon_init {
enum {
RADEON_INIT_CP = 0x01,
RADEON_CLEANUP_CP = 0x02
} func;
int sarea_priv_offset;
int is_pci;
int cp_mode;
int agp_size;
int ring_size;
int usec_timeout;
unsigned int fb_bpp;
unsigned int front_offset, front_pitch;
unsigned int back_offset, back_pitch;
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
unsigned int fb_offset;
unsigned int mmio_offset;
unsigned int ring_offset;
unsigned int ring_rptr_offset;
unsigned int buffers_offset;
unsigned int agp_textures_offset;
} drm_radeon_init_t;
typedef struct drm_radeon_cp_stop {
int flush;
int idle;
} drm_radeon_cp_stop_t;
typedef struct drm_radeon_fullscreen {
enum {
RADEON_INIT_FULLSCREEN = 0x01,
RADEON_CLEANUP_FULLSCREEN = 0x02
} func;
} drm_radeon_fullscreen_t;
#define CLEAR_X1 0
#define CLEAR_Y1 1
#define CLEAR_X2 2
#define CLEAR_Y2 3
#define CLEAR_DEPTH 4
typedef struct drm_radeon_clear {
unsigned int flags;
int x, y, w, h;
unsigned int clear_color;
unsigned int clear_depth;
union {
float f[5];
unsigned int ui[5];
} rect;
} drm_radeon_clear_t;
typedef struct drm_radeon_vertex {
int prim;
int idx; /* Index of vertex buffer */
int count; /* Number of vertices in buffer */
int discard; /* Client finished with buffer? */
} drm_radeon_vertex_t;
typedef struct drm_radeon_indices {
int prim;
int idx;
int start;
int end;
int discard; /* Client finished with buffer? */
} drm_radeon_indices_t;
typedef struct drm_radeon_blit {
int idx;
int pitch;
int offset;
int format;
unsigned short x, y;
unsigned short width, height;
} drm_radeon_blit_t;
typedef struct drm_radeon_stipple {
unsigned int *mask;
} drm_radeon_stipple_t;
typedef struct drm_radeon_indirect {
int idx;
int start;
int end;
int discard;
} drm_radeon_indirect_t;
#endif

702
linux/radeon_drv.c Normal file
View File

@ -0,0 +1,702 @@
/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Kevin E. Martin <martin@valinux.com>
* Rickard E. (Rik) Faith <faith@valinux.com>
*
*/
#include <linux/config.h>
#include "drmP.h"
#include "radeon_drv.h"
#define RADEON_NAME "radeon"
#define RADEON_DESC "ATI Radeon"
#define RADEON_DATE "20010105"
#define RADEON_MAJOR 1
#define RADEON_MINOR 0
#define RADEON_PATCHLEVEL 0
static drm_device_t radeon_device;
drm_ctx_t radeon_res_ctx;
static struct file_operations radeon_fops = {
#if LINUX_VERSION_CODE >= 0x020400
/* This started being used during 2.4.0-test */
owner: THIS_MODULE,
#endif
open: radeon_open,
flush: drm_flush,
release: radeon_release,
ioctl: radeon_ioctl,
mmap: drm_mmap,
read: drm_read,
fasync: drm_fasync,
poll: drm_poll,
};
static struct miscdevice radeon_misc = {
minor: MISC_DYNAMIC_MINOR,
name: RADEON_NAME,
fops: &radeon_fops,
};
static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { radeon_version, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { radeon_addbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { radeon_mapbufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { radeon_addctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { radeon_rmctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { radeon_modctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { radeon_getctx, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { radeon_switchctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { radeon_newctx, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { radeon_resctx, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { radeon_lock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { radeon_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
};
#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
#ifdef MODULE
static char *radeon = NULL;
#endif
MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("radeon");
MODULE_PARM(radeon, "s");
#ifndef MODULE
/* radeon_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
* routine, drm_parse_drm.
*/
static int __init radeon_options(char *str)
{
drm_parse_options(str);
return 1;
}
__setup("radeon=", radeon_options);
#endif
static int radeon_setup(drm_device_t *dev)
{
int i;
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
dev->buf_use = 0;
atomic_set(&dev->buf_alloc, 0);
drm_dma_setup(dev);
atomic_set(&dev->total_open, 0);
atomic_set(&dev->total_close, 0);
atomic_set(&dev->total_ioctl, 0);
atomic_set(&dev->total_irq, 0);
atomic_set(&dev->total_ctx, 0);
atomic_set(&dev->total_locks, 0);
atomic_set(&dev->total_unlocks, 0);
atomic_set(&dev->total_contends, 0);
atomic_set(&dev->total_sleeps, 0);
for (i = 0; i < DRM_HASH_SIZE; i++) {
dev->magiclist[i].head = NULL;
dev->magiclist[i].tail = NULL;
}
dev->maplist = NULL;
dev->map_count = 0;
dev->vmalist = NULL;
dev->lock.hw_lock = NULL;
init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
dev->queue_slots = 0;
dev->queuelist = NULL;
dev->irq = 0;
dev->context_flag = 0;
dev->interrupt_flag = 0;
dev->dma_flag = 0;
dev->last_context = 0;
dev->last_switch = 0;
dev->last_checked = 0;
init_timer(&dev->timer);
init_waitqueue_head(&dev->context_wait);
dev->ctx_start = 0;
dev->lck_start = 0;
dev->buf_rp = dev->buf;
dev->buf_wp = dev->buf;
dev->buf_end = dev->buf + DRM_BSZ;
dev->buf_async = NULL;
init_waitqueue_head(&dev->buf_readers);
init_waitqueue_head(&dev->buf_writers);
radeon_res_ctx.handle = -1;
DRM_DEBUG("\n");
/* The kernel's context could be created here, but is now created
in drm_dma_enqueue. This is more resource-efficient for
hardware that does not do DMA, but may mean that
drm_select_queue fails between the time the interrupt is
initialized and the time the queues are initialized. */
return 0;
}
static int radeon_takedown(drm_device_t *dev)
{
int i;
drm_magic_entry_t *pt, *next;
drm_map_t *map;
drm_vma_entry_t *vma, *vma_next;
DRM_DEBUG("\n");
down(&dev->struct_sem);
del_timer(&dev->timer);
if (dev->devname) {
drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
dev->devname = NULL;
}
if (dev->unique) {
drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
dev->unique = NULL;
dev->unique_len = 0;
}
/* Clear pid list */
for (i = 0; i < DRM_HASH_SIZE; i++) {
for (pt = dev->magiclist[i].head; pt; pt = next) {
next = pt->next;
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
}
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
/* Clear AGP information */
if (dev->agp) {
drm_agp_mem_t *entry;
drm_agp_mem_t *nexte;
/* Remove AGP resources, but leave dev->agp
intact until radeon_cleanup is called. */
for (entry = dev->agp->memory; entry; entry = nexte) {
nexte = entry->next;
if (entry->bound) drm_unbind_agp(entry->memory);
drm_free_agp(entry->memory, entry->pages);
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
}
dev->agp->memory = NULL;
if (dev->agp->acquired) _drm_agp_release();
dev->agp->acquired = 0;
dev->agp->enabled = 0;
}
#endif
/* Clear vma list (only built for debugging) */
if (dev->vmalist) {
for (vma = dev->vmalist; vma; vma = vma_next) {
vma_next = vma->next;
drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
}
dev->vmalist = NULL;
}
/* Clear map area and mtrr information */
if (dev->maplist) {
for (i = 0; i < dev->map_count; i++) {
map = dev->maplist[i];
switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
#ifdef CONFIG_MTRR
if (map->mtrr >= 0) {
int retcode;
retcode = mtrr_del(map->mtrr,
map->offset,
map->size);
DRM_DEBUG("mtrr_del = %d\n", retcode);
}
#endif
drm_ioremapfree(map->handle, map->size);
break;
case _DRM_SHM:
drm_free_pages((unsigned long)map->handle,
drm_order(map->size)
- PAGE_SHIFT,
DRM_MEM_SAREA);
break;
case _DRM_AGP:
/* Do nothing here, because this is all
handled in the AGP/GART driver. */
break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
drm_free(dev->maplist,
dev->map_count * sizeof(*dev->maplist),
DRM_MEM_MAPS);
dev->maplist = NULL;
dev->map_count = 0;
}
drm_dma_takedown(dev);
dev->queue_count = 0;
if (dev->lock.hw_lock) {
dev->lock.hw_lock = NULL; /* SHM removed */
dev->lock.pid = 0;
wake_up_interruptible(&dev->lock.lock_queue);
}
up(&dev->struct_sem);
return 0;
}
/* radeon_init is called via init_module at module load time, or via
* linux/init/main.c (this is not currently supported). */
static int __init radeon_init(void)
{
int retcode;
drm_device_t *dev = &radeon_device;
DRM_DEBUG("\n");
memset((void *)dev, 0, sizeof(*dev));
dev->count_lock = SPIN_LOCK_UNLOCKED;
sema_init(&dev->struct_sem, 1);
#ifdef MODULE
drm_parse_options(radeon);
#endif
if ((retcode = misc_register(&radeon_misc))) {
DRM_ERROR("Cannot register \"%s\"\n", RADEON_NAME);
return retcode;
}
dev->device = MKDEV(MISC_MAJOR, radeon_misc.minor);
dev->name = RADEON_NAME;
drm_mem_init();
drm_proc_init(dev);
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
dev->agp = drm_agp_init();
if (dev->agp == NULL) {
DRM_ERROR("Cannot initialize agpgart module.\n");
drm_proc_cleanup();
misc_deregister(&radeon_misc);
radeon_takedown(dev);
return -ENOMEM;
}
#ifdef CONFIG_MTRR
dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
dev->agp->agp_info.aper_size*1024*1024,
MTRR_TYPE_WRCOMB,
1);
#endif
#endif
if((retcode = drm_ctxbitmap_init(dev))) {
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
drm_proc_cleanup();
misc_deregister(&radeon_misc);
radeon_takedown(dev);
return retcode;
}
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
RADEON_NAME,
RADEON_MAJOR,
RADEON_MINOR,
RADEON_PATCHLEVEL,
RADEON_DATE,
radeon_misc.minor);
return 0;
}
/* radeon_cleanup is called via cleanup_module at module unload time. */
static void __exit radeon_cleanup(void)
{
drm_device_t *dev = &radeon_device;
DRM_DEBUG("\n");
drm_proc_cleanup();
if (misc_deregister(&radeon_misc)) {
DRM_ERROR("Cannot unload module\n");
} else {
DRM_INFO("Module unloaded\n");
}
drm_ctxbitmap_cleanup(dev);
radeon_takedown(dev);
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (dev->agp) {
drm_agp_uninit();
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
dev->agp = NULL;
}
#endif
}
module_init(radeon_init);
module_exit(radeon_cleanup);
int radeon_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_version_t version;
int len;
if (copy_from_user(&version,
(drm_version_t *)arg,
sizeof(version)))
return -EFAULT;
#define DRM_COPY(name,value) \
len = strlen(value); \
if (len > name##_len) len = name##_len; \
name##_len = strlen(value); \
if (len && name) { \
if (copy_to_user(name, value, len)) \
return -EFAULT; \
}
version.version_major = RADEON_MAJOR;
version.version_minor = RADEON_MINOR;
version.version_patchlevel = RADEON_PATCHLEVEL;
DRM_COPY(version.name, RADEON_NAME);
DRM_COPY(version.date, RADEON_DATE);
DRM_COPY(version.desc, RADEON_DESC);
if (copy_to_user((drm_version_t *)arg,
&version,
sizeof(version)))
return -EFAULT;
return 0;
}
int radeon_open(struct inode *inode, struct file *filp)
{
drm_device_t *dev = &radeon_device;
int retcode = 0;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
#endif
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
spin_unlock(&dev->count_lock);
return radeon_setup(dev);
}
spin_unlock(&dev->count_lock);
}
return retcode;
}
int radeon_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
int retcode = 0;
lock_kernel();
dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
/* Force the cleanup of page flipping when required */
if ( dev->dev_private ) {
drm_radeon_private_t *dev_priv = dev->dev_private;
if ( dev_priv->page_flipping ) {
radeon_do_cleanup_pageflip( dev );
}
}
if (!(retcode = drm_release(inode, filp))) {
#if LINUX_VERSION_CODE < 0x020333
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
#endif
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
if (atomic_read(&dev->ioctl_count) || dev->blocked) {
DRM_ERROR("Device busy: %d %d\n",
atomic_read(&dev->ioctl_count),
dev->blocked);
spin_unlock(&dev->count_lock);
unlock_kernel();
return -EBUSY;
}
spin_unlock(&dev->count_lock);
unlock_kernel();
return radeon_takedown(dev);
}
spin_unlock(&dev->count_lock);
}
unlock_kernel();
return retcode;
}
/* radeon_ioctl is called whenever a process performs an ioctl on /dev/drm. */
int radeon_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
int nr = DRM_IOCTL_NR(cmd);
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
int retcode = 0;
drm_ioctl_desc_t *ioctl;
drm_ioctl_t *func;
atomic_inc(&dev->ioctl_count);
atomic_inc(&dev->total_ioctl);
++priv->ioctl_count;
DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
current->pid, cmd, nr, dev->device, priv->authenticated);
if (nr >= RADEON_IOCTL_COUNT) {
retcode = -EINVAL;
} else {
ioctl = &radeon_ioctls[nr];
func = ioctl->func;
if (!func) {
DRM_DEBUG("no function\n");
retcode = -EINVAL;
} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
|| (ioctl->auth_needed && !priv->authenticated)) {
retcode = -EACCES;
} else {
retcode = (func)(inode, filp, cmd, arg);
}
}
atomic_dec(&dev->ioctl_count);
return retcode;
}
int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DECLARE_WAITQUEUE(entry, current);
int ret = 0;
drm_lock_t lock;
#if DRM_DMA_HISTOGRAM
cycles_t start;
dev->lck_start = start = get_cycles();
#endif
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
return -EFAULT;
if (lock.context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
current->pid, lock.context);
return -EINVAL;
}
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
lock.context, current->pid, dev->lock.hw_lock->lock,
lock.flags);
if (lock.context < 0 /* || lock.context >= dev->queue_count */)
return -EINVAL;
if (!ret) {
add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
current->state = TASK_INTERRUPTIBLE;
if (!dev->lock.hw_lock) {
/* Device has been unregistered */
ret = -EINTR;
break;
}
if (drm_lock_take(&dev->lock.hw_lock->lock,
lock.context)) {
dev->lock.pid = current->pid;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->total_locks);
break; /* Got lock */
}
/* Contention */
atomic_inc(&dev->total_sleeps);
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
current->state = TASK_RUNNING;
remove_wait_queue(&dev->lock.lock_queue, &entry);
}
if (!ret) {
sigemptyset(&dev->sigmask);
sigaddset(&dev->sigmask, SIGSTOP);
sigaddset(&dev->sigmask, SIGTSTP);
sigaddset(&dev->sigmask, SIGTTIN);
sigaddset(&dev->sigmask, SIGTTOU);
dev->sigdata.context = lock.context;
dev->sigdata.lock = dev->lock.hw_lock;
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
if (lock.flags & _DRM_LOCK_READY) {
/* Wait for space in DMA/FIFO */
}
if (lock.flags & _DRM_LOCK_QUIESCENT) {
/* Make hardware quiescent */
DRM_DEBUG("not quiescent!\n");
#if 0
radeon_quiescent(dev);
#endif
}
}
#if LINUX_VERSION_CODE < 0x020400
if (lock.context != radeon_res_ctx.handle) {
current->counter = 5;
current->priority = DEF_PRIORITY/4;
}
#endif
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
#endif
return ret;
}
int radeon_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_lock_t lock;
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
return -EFAULT;
if (lock.context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
current->pid, lock.context);
return -EINVAL;
}
DRM_DEBUG("%d frees lock (%d holds)\n",
lock.context,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
atomic_inc(&dev->total_unlocks);
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
atomic_inc(&dev->total_contends);
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
/* FIXME: Try to send data to card here */
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
}
#if LINUX_VERSION_CODE < 0x020400
if (lock.context != radeon_res_ctx.handle) {
current->counter = 5;
current->priority = DEF_PRIORITY;
}
#endif
unblock_all_signals();
return 0;
}

709
linux/radeon_drv.h Normal file
View File

@ -0,0 +1,709 @@
/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*-
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
*
*/
#ifndef __RADEON_DRV_H__
#define __RADEON_DRV_H__
typedef struct drm_radeon_freelist {
unsigned int age;
drm_buf_t *buf;
struct drm_radeon_freelist *next;
struct drm_radeon_freelist *prev;
} drm_radeon_freelist_t;
typedef struct drm_radeon_ring_buffer {
u32 *start;
u32 *end;
int size;
int size_l2qw;
volatile u32 *head;
u32 tail;
u32 tail_mask;
int space;
} drm_radeon_ring_buffer_t;
typedef struct drm_radeon_depth_clear_t {
u32 rb3d_cntl;
u32 rb3d_zstencilcntl;
u32 se_cntl;
} drm_radeon_depth_clear_t;
typedef struct drm_radeon_private {
drm_radeon_ring_buffer_t ring;
drm_radeon_sarea_t *sarea_priv;
int agp_size;
u32 agp_vm_start;
u32 agp_buffers_offset;
int cp_mode;
int cp_running;
drm_radeon_freelist_t *head;
drm_radeon_freelist_t *tail;
/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist
code is used. Note this hides a problem with the scratch register
(used to keep track of last buffer completed) being written to before
the last buffer has actually completed rendering. */
#define ROTATE_BUFS 1
#if ROTATE_BUFS
int last_buf;
#endif
volatile u32 *scratch;
int usec_timeout;
int is_pci;
atomic_t idle_count;
int page_flipping;
int current_page;
u32 crtc_offset;
u32 crtc_offset_cntl;
unsigned int color_fmt;
unsigned int front_offset;
unsigned int front_pitch;
unsigned int back_offset;
unsigned int back_pitch;
unsigned int depth_fmt;
unsigned int depth_offset;
unsigned int depth_pitch;
u32 front_pitch_offset;
u32 back_pitch_offset;
u32 depth_pitch_offset;
drm_radeon_depth_clear_t depth_clear;
drm_map_t *sarea;
drm_map_t *fb;
drm_map_t *mmio;
drm_map_t *cp_ring;
drm_map_t *ring_rptr;
drm_map_t *buffers;
drm_map_t *agp_textures;
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
u32 age;
int prim;
int discard;
int dispatched;
drm_radeon_freelist_t *list_entry;
} drm_radeon_buf_priv_t;
/* radeon_drv.c */
extern int radeon_version( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_open( struct inode *inode, struct file *filp );
extern int radeon_release( struct inode *inode, struct file *filp );
extern int radeon_ioctl( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_lock( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_unlock( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* radeon_cp.c */
extern int radeon_cp_init( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_start( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_stop( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_idle( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_engine_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern void radeon_freelist_reset( drm_device_t *dev );
extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
extern void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv );
extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
/* radeon_state.c */
extern int radeon_cp_clear( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indices( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* radeon_bufs.c */
extern int radeon_addbufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_mapbufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* radeon_context.c */
extern int radeon_resctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_addctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_modctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_getctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_switchctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_newctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_rmctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int radeon_context_switch(drm_device_t *dev, int old, int new);
extern int radeon_context_switch_complete(drm_device_t *dev, int new);
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
*/
#define RADEON_AUX_SCISSOR_CNTL 0x26f0
# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26)
# define RADEON_SCISSOR_0_ENABLE (1 << 28)
# define RADEON_SCISSOR_1_ENABLE (1 << 29)
# define RADEON_SCISSOR_2_ENABLE (1 << 30)
#define RADEON_BUS_CNTL 0x0030
# define RADEON_BUS_MASTER_DIS (1 << 6)
#define RADEON_CLOCK_CNTL_DATA 0x000c
# define RADEON_PLL_WR_EN (1 << 7)
#define RADEON_CLOCK_CNTL_INDEX 0x0008
#define RADEON_CONFIG_APER_SIZE 0x0108
#define RADEON_CRTC_OFFSET 0x0224
#define RADEON_CRTC_OFFSET_CNTL 0x0228
# define RADEON_CRTC_TILE_EN (1 << 15)
# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
#define RADEON_RB3D_COLORPITCH 0x1c48
#define RADEON_RB3D_DEPTHCLEARVALUE 0x1c30
#define RADEON_RB3D_DEPTHXY_OFFSET 0x1c60
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4)
# define RADEON_GMC_BRUSH_NONE (15 << 4)
# define RADEON_GMC_DST_16BPP (4 << 8)
# define RADEON_GMC_DST_24BPP (5 << 8)
# define RADEON_GMC_DST_32BPP (6 << 8)
# define RADEON_GMC_DST_DATATYPE_SHIFT 8
# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)
# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24)
# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24)
# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28)
# define RADEON_GMC_WR_MSK_DIS (1 << 30)
# define RADEON_ROP3_S 0x00cc0000
# define RADEON_ROP3_P 0x00f00000
#define RADEON_DP_WRITE_MASK 0x16cc
#define RADEON_DST_PITCH_OFFSET 0x142c
#define RADEON_DST_PITCH_OFFSET_C 0x1c80
# define RADEON_DST_TILE_LINEAR (0 << 30)
# define RADEON_DST_TILE_MACRO (1 << 30)
# define RADEON_DST_TILE_MICRO (2 << 30)
# define RADEON_DST_TILE_BOTH (3 << 30)
#define RADEON_SCRATCH_REG0 0x15e0
#define RADEON_SCRATCH_REG1 0x15e4
#define RADEON_SCRATCH_REG2 0x15e8
#define RADEON_SCRATCH_REG3 0x15ec
#define RADEON_SCRATCH_REG4 0x15f0
#define RADEON_SCRATCH_REG5 0x15f4
#define RADEON_SCRATCH_UMSK 0x0770
#define RADEON_SCRATCH_ADDR 0x0774
#define RADEON_HOST_PATH_CNTL 0x0130
# define RADEON_HDP_SOFT_RESET (1 << 26)
# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28)
#define RADEON_ISYNC_CNTL 0x1724
# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1)
# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2)
# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3)
# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
#define RADEON_MC_AGP_LOCATION 0x014c
#define RADEON_MC_FB_LOCATION 0x0148
#define RADEON_MCLK_CNTL 0x0012
#define RADEON_PP_BORDER_COLOR_0 0x1d40
#define RADEON_PP_BORDER_COLOR_1 0x1d44
#define RADEON_PP_BORDER_COLOR_2 0x1d48
#define RADEON_PP_CNTL 0x1c38
# define RADEON_SCISSOR_ENABLE (1 << 1)
#define RADEON_PP_LUM_MATRIX 0x1d00
#define RADEON_PP_MISC 0x1c14
#define RADEON_PP_ROT_MATRIX_0 0x1d58
#define RADEON_PP_TXFILTER_0 0x1c54
#define RADEON_PP_TXFILTER_1 0x1c6c
#define RADEON_PP_TXFILTER_2 0x1c84
#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c
# define RADEON_RB2D_DC_FLUSH (3 << 0)
# define RADEON_RB2D_DC_FREE (3 << 2)
# define RADEON_RB2D_DC_FLUSH_ALL 0xf
# define RADEON_RB2D_DC_BUSY (1 << 31)
#define RADEON_RB3D_CNTL 0x1c3c
# define RADEON_ALPHA_BLEND_ENABLE (1 << 0)
# define RADEON_PLANE_MASK_ENABLE (1 << 1)
# define RADEON_DITHER_ENABLE (1 << 2)
# define RADEON_ROUND_ENABLE (1 << 3)
# define RADEON_SCALE_DITHER_ENABLE (1 << 4)
# define RADEON_DITHER_INIT (1 << 5)
# define RADEON_ROP_ENABLE (1 << 6)
# define RADEON_STENCIL_ENABLE (1 << 7)
# define RADEON_Z_ENABLE (1 << 8)
# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9)
# define RADEON_ZBLOCK8 (0 << 15)
# define RADEON_ZBLOCK16 (1 << 15)
#define RADEON_RB3D_DEPTHOFFSET 0x1c24
#define RADEON_RB3D_PLANEMASK 0x1d84
#define RADEON_RB3D_STENCILREFMASK 0x1d7c
#define RADEON_RB3D_ZCACHE_MODE 0x3250
#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254
# define RADEON_RB3D_ZC_FLUSH (1 << 0)
# define RADEON_RB3D_ZC_FREE (1 << 2)
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
# define RADEON_RB3D_ZC_BUSY (1 << 31)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4)
# define RADEON_Z_TEST_ALWAYS (7 << 4)
# define RADEON_STENCIL_TEST_ALWAYS (7 << 12)
# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16)
# define RADEON_STENCIL_ZPASS_KEEP (0 << 20)
# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20)
# define RADEON_Z_WRITE_ENABLE (1 << 30)
#define RADEON_RBBM_SOFT_RESET 0x00f0
# define RADEON_SOFT_RESET_CP (1 << 0)
# define RADEON_SOFT_RESET_HI (1 << 1)
# define RADEON_SOFT_RESET_SE (1 << 2)
# define RADEON_SOFT_RESET_RE (1 << 3)
# define RADEON_SOFT_RESET_PP (1 << 4)
# define RADEON_SOFT_RESET_E2 (1 << 5)
# define RADEON_SOFT_RESET_RB (1 << 6)
# define RADEON_SOFT_RESET_HDP (1 << 7)
#define RADEON_RBBM_STATUS 0x0e40
# define RADEON_RBBM_FIFOCNT_MASK 0x007f
# define RADEON_RBBM_ACTIVE (1 << 31)
#define RADEON_RE_LINE_PATTERN 0x1cd0
#define RADEON_RE_MISC 0x26c4
#define RADEON_RE_TOP_LEFT 0x26c0
#define RADEON_RE_WIDTH_HEIGHT 0x1c44
#define RADEON_RE_STIPPLE_ADDR 0x1cc8
#define RADEON_RE_STIPPLE_DATA 0x1ccc
#define RADEON_SCISSOR_TL_0 0x1cd8
#define RADEON_SCISSOR_BR_0 0x1cdc
#define RADEON_SCISSOR_TL_1 0x1ce0
#define RADEON_SCISSOR_BR_1 0x1ce4
#define RADEON_SCISSOR_TL_2 0x1ce8
#define RADEON_SCISSOR_BR_2 0x1cec
#define RADEON_SE_COORD_FMT 0x1c50
#define RADEON_SE_CNTL 0x1c4c
# define RADEON_FFACE_CULL_CW (0 << 0)
# define RADEON_BFACE_SOLID (3 << 1)
# define RADEON_FFACE_SOLID (3 << 3)
# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6)
# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8)
# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8)
# define RADEON_ALPHA_SHADE_FLAT (1 << 10)
# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10)
# define RADEON_SPECULAR_SHADE_FLAT (1 << 12)
# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12)
# define RADEON_FOG_SHADE_FLAT (1 << 14)
# define RADEON_FOG_SHADE_GOURAUD (2 << 14)
# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24)
# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25)
# define RADEON_VTX_PIX_CENTER_OGL (1 << 27)
# define RADEON_ROUND_MODE_TRUNC (0 << 28)
# define RADEON_ROUND_PREC_8TH_PIX (1 << 30)
#define RADEON_SE_CNTL_STATUS 0x2140
#define RADEON_SE_LINE_WIDTH 0x1db8
#define RADEON_SE_VPORT_XSCALE 0x1d98
#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8
#define RADEON_SURFACE_ACCESS_CLR 0x0bfc
#define RADEON_SURFACE_CNTL 0x0b00
# define RADEON_SURF_TRANSLATION_DIS (1 << 8)
# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20)
# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20)
# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20)
# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20)
# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22)
# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22)
# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22)
# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22)
#define RADEON_SURFACE0_INFO 0x0b0c
# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0)
# define RADEON_SURF_TILE_MODE_MASK (3 << 16)
# define RADEON_SURF_TILE_MODE_MACRO (0 << 16)
# define RADEON_SURF_TILE_MODE_MICRO (1 << 16)
# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16)
# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16)
#define RADEON_SURFACE0_LOWER_BOUND 0x0b04
#define RADEON_SURFACE0_UPPER_BOUND 0x0b08
#define RADEON_SURFACE1_INFO 0x0b1c
#define RADEON_SURFACE1_LOWER_BOUND 0x0b14
#define RADEON_SURFACE1_UPPER_BOUND 0x0b18
#define RADEON_SURFACE2_INFO 0x0b2c
#define RADEON_SURFACE2_LOWER_BOUND 0x0b24
#define RADEON_SURFACE2_UPPER_BOUND 0x0b28
#define RADEON_SURFACE3_INFO 0x0b3c
#define RADEON_SURFACE3_LOWER_BOUND 0x0b34
#define RADEON_SURFACE3_UPPER_BOUND 0x0b38
#define RADEON_SURFACE4_INFO 0x0b4c
#define RADEON_SURFACE4_LOWER_BOUND 0x0b44
#define RADEON_SURFACE4_UPPER_BOUND 0x0b48
#define RADEON_SURFACE5_INFO 0x0b5c
#define RADEON_SURFACE5_LOWER_BOUND 0x0b54
#define RADEON_SURFACE5_UPPER_BOUND 0x0b58
#define RADEON_SURFACE6_INFO 0x0b6c
#define RADEON_SURFACE6_LOWER_BOUND 0x0b64
#define RADEON_SURFACE6_UPPER_BOUND 0x0b68
#define RADEON_SURFACE7_INFO 0x0b7c
#define RADEON_SURFACE7_LOWER_BOUND 0x0b74
#define RADEON_SURFACE7_UPPER_BOUND 0x0b78
#define RADEON_SW_SEMAPHORE 0x013c
#define RADEON_WAIT_UNTIL 0x1720
# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
#define RADEON_RB3D_ZMASKOFFSET 0x1c34
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
/* CP registers */
#define RADEON_CP_ME_RAM_ADDR 0x07d4
#define RADEON_CP_ME_RAM_RADDR 0x07d8
#define RADEON_CP_ME_RAM_DATAH 0x07dc
#define RADEON_CP_ME_RAM_DATAL 0x07e0
#define RADEON_CP_RB_BASE 0x0700
#define RADEON_CP_RB_CNTL 0x0704
#define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714
#define RADEON_CP_RB_WPTR_DELAY 0x0718
# define RADEON_PRE_WRITE_TIMER_SHIFT 0
# define RADEON_PRE_WRITE_LIMIT_SHIFT 23
#define RADEON_CP_IB_BASE 0x0738
#define RADEON_CP_CSQ_CNTL 0x0740
# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0)
# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28)
# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28)
# define RADEON_CSQ_PRIBM_INDDIS (2 << 28)
# define RADEON_CSQ_PRIPIO_INDBM (3 << 28)
# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
#define RADEON_AIC_CNTL 0x01d0
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
/* CP command packets */
#define RADEON_CP_PACKET0 0x00000000
# define RADEON_ONE_REG_WR (1 << 15)
#define RADEON_CP_PACKET1 0x40000000
#define RADEON_CP_PACKET2 0x80000000
#define RADEON_CP_PACKET3 0xC0000000
# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
# define RADEON_WAIT_FOR_IDLE 0x00002600
# define RADEON_3D_DRAW_IMMD 0x00002900
# define RADEON_3D_CLEAR_ZMASK 0x00003200
# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
# define RADEON_CNTL_PAINT_MULTI 0x00009A00
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
#define RADEON_CP_PACKET_MASK 0xC0000000
#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
#define RADEON_CP_PACKET0_REG_MASK 0x000007ff
#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
#define RADEON_VTX_Z_PRESENT (1 << 31)
#define RADEON_PRIM_TYPE_NONE (0 << 0)
#define RADEON_PRIM_TYPE_POINT (1 << 0)
#define RADEON_PRIM_TYPE_LINE (2 << 0)
#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0)
#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0)
#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0)
#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0)
#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0)
#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0)
#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
#define RADEON_PRIM_WALK_IND (1 << 4)
#define RADEON_PRIM_WALK_LIST (2 << 4)
#define RADEON_PRIM_WALK_RING (3 << 4)
#define RADEON_COLOR_ORDER_BGRA (0 << 6)
#define RADEON_COLOR_ORDER_RGBA (1 << 6)
#define RADEON_MAOS_ENABLE (1 << 7)
#define RADEON_VTX_FMT_R128_MODE (0 << 8)
#define RADEON_VTX_FMT_RADEON_MODE (1 << 8)
#define RADEON_NUM_VERTICES_SHIFT 16
#define RADEON_COLOR_FORMAT_CI8 2
#define RADEON_COLOR_FORMAT_ARGB1555 3
#define RADEON_COLOR_FORMAT_RGB565 4
#define RADEON_COLOR_FORMAT_ARGB8888 6
#define RADEON_COLOR_FORMAT_RGB332 7
#define RADEON_COLOR_FORMAT_RGB8 9
#define RADEON_COLOR_FORMAT_ARGB4444 15
#define RADEON_TXF_8BPP_I 0
#define RADEON_TXF_16BPP_AI88 1
#define RADEON_TXF_8BPP_RGB332 2
#define RADEON_TXF_16BPP_ARGB1555 3
#define RADEON_TXF_16BPP_RGB565 4
#define RADEON_TXF_16BPP_ARGB4444 5
#define RADEON_TXF_32BPP_ARGB8888 6
#define RADEON_TXF_32BPP_RGBA8888 7
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0
#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1
#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2
#define RADEON_LAST_DISPATCH 1
#define RADEON_MAX_VB_AGE 0x7fffffff
#define RADEON_MAX_VB_VERTS (0xffff)
#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg)
#define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg)
#define RADEON_READ(reg) RADEON_DEREF(reg)
#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0)
#define RADEON_DEREF8(reg) *(__volatile__ u8 *)RADEON_ADDR(reg)
#define RADEON_READ8(reg) RADEON_DEREF8(reg)
#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0)
#define RADEON_WRITE_PLL(addr,val) \
do { \
RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \
((addr) & 0x1f) | RADEON_PLL_WR_EN); \
RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \
} while (0)
extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
(RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET1( reg0, reg1 ) \
(RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2))
#define CP_PACKET2() \
(RADEON_CP_PACKET2)
#define CP_PACKET3( pkt, n ) \
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
/* ================================================================
* Engine control helper macros
*/
#define RADEON_WAIT_UNTIL_2D_IDLE() \
do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
#define RADEON_WAIT_UNTIL_3D_IDLE() \
do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
#define RADEON_WAIT_UNTIL_IDLE() \
do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \
do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \
} while (0)
#define RADEON_FLUSH_CACHE() \
do { \
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB2D_DC_FLUSH ); \
} while (0)
#define RADEON_PURGE_CACHE() \
do { \
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \
} while (0)
#define RADEON_FLUSH_ZCACHE() \
do { \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
} while (0)
#define RADEON_PURGE_ZCACHE() \
do { \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
} while (0)
/* ================================================================
* Misc helper macros
*/
#define VB_AGE_CHECK_WITH_RET( dev_priv ) \
do { \
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
int __ret = radeon_do_cp_idle( dev_priv ); \
if ( __ret < 0 ) return __ret; \
sarea_priv->last_dispatch = 0; \
radeon_freelist_reset( dev ); \
} \
} while (0)
#define RADEON_DISPATCH_AGE( age ) \
do { \
OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
#define RADEON_FRAME_AGE( age ) \
do { \
OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
#define RADEON_CLEAR_AGE( age ) \
do { \
OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
/* ================================================================
* Ring control
*/
#define radeon_flush_write_combine() mb()
#define RADEON_VERBOSE 0
#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
n, __FUNCTION__ ); \
} \
if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \
radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
mask = dev_priv->ring.tail_mask; \
} while (0)
#define ADVANCE_RING() do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
radeon_flush_write_combine(); \
dev_priv->ring.tail = write; \
RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \
} while (0)
#define OUT_RING( x ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), write ); \
} \
ring[write++] = (x); \
write &= mask; \
} while (0)
#define RADEON_PERFORMANCE_BOXES 0
#endif /* __RADEON_DRV_H__ */

1447
linux/radeon_state.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,30 +2,19 @@
#ifndef _sis_drm_public_h_
#define _sis_drm_public_h_
typedef struct {
typedef struct {
int context;
unsigned int offset;
unsigned int size;
unsigned int free;
} drm_sis_mem_t;
} drm_sis_mem_t;
typedef struct {
typedef struct {
unsigned int offset, size;
} drm_sis_agp_t;
} drm_sis_agp_t;
typedef struct {
typedef struct {
unsigned int left, right;
} drm_sis_flip_t;
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
} drm_sis_flip_t;
#endif

View File

@ -82,6 +82,7 @@ typedef struct drm_clip_rect {
#include "mga_drm.h"
#include "i810_drm.h"
#include "r128_drm.h"
#include "radeon_drm.h"
#ifdef CONFIG_DRM_SIS
#include "sis_drm.h"
#endif
@ -297,100 +298,117 @@ typedef struct drm_agp_info {
unsigned short id_device;
} drm_agp_info_t;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
/* Mga specific ioctls */
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
/* I810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48)
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#ifdef CONFIG_DRM_SIS
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#endif
#endif

View File

@ -82,6 +82,7 @@ typedef struct drm_clip_rect {
#include "mga_drm.h"
#include "i810_drm.h"
#include "r128_drm.h"
#include "radeon_drm.h"
#ifdef CONFIG_DRM_SIS
#include "sis_drm.h"
#endif
@ -297,100 +298,117 @@ typedef struct drm_agp_info {
unsigned short id_device;
} drm_agp_info_t;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
/* Mga specific ioctls */
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t)
/* I810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48)
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t)
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
/* Radeon specific ioctls */
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41)
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t)
#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43)
#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44)
#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45)
#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t)
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#ifdef CONFIG_DRM_SIS
/* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t)
#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t)
#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t)
#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t)
#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49)
#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50)
#endif
#endif