mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-23 16:40:12 +01:00
Merge branch 'master' of git://anongit.freedesktop.org/git/mesa/drm into nouveau-1
This commit is contained in:
commit
93fee5cf22
32 changed files with 1426 additions and 521 deletions
|
|
@ -170,7 +170,7 @@ MALLOC_DECLARE(M_DRM);
|
||||||
#define wait_queue_head_t atomic_t
|
#define wait_queue_head_t atomic_t
|
||||||
#define DRM_WAKEUP(w) wakeup((void *)w)
|
#define DRM_WAKEUP(w) wakeup((void *)w)
|
||||||
#define DRM_WAKEUP_INT(w) wakeup(w)
|
#define DRM_WAKEUP_INT(w) wakeup(w)
|
||||||
#define DRM_INIT_WAITQUEUE(queue) do {} while (0)
|
#define DRM_INIT_WAITQUEUE(queue) do {(void)(queue);} while (0)
|
||||||
|
|
||||||
#if defined(__FreeBSD__) && __FreeBSD_version < 502109
|
#if defined(__FreeBSD__) && __FreeBSD_version < 502109
|
||||||
#define bus_alloc_resource_any(dev, type, rid, flags) \
|
#define bus_alloc_resource_any(dev, type, rid, flags) \
|
||||||
|
|
@ -270,6 +270,7 @@ extern struct cfdriver drm_cd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned long dma_addr_t;
|
typedef unsigned long dma_addr_t;
|
||||||
|
typedef u_int64_t u64;
|
||||||
typedef u_int32_t u32;
|
typedef u_int32_t u32;
|
||||||
typedef u_int16_t u16;
|
typedef u_int16_t u16;
|
||||||
typedef u_int8_t u8;
|
typedef u_int8_t u8;
|
||||||
|
|
@ -713,6 +714,9 @@ struct drm_device {
|
||||||
struct drm_driver_info driver;
|
struct drm_driver_info driver;
|
||||||
drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
|
drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
|
||||||
|
|
||||||
|
u_int16_t pci_device; /* PCI device id */
|
||||||
|
u_int16_t pci_vendor; /* PCI vendor id */
|
||||||
|
|
||||||
char *unique; /* Unique identifier: e.g., busid */
|
char *unique; /* Unique identifier: e.g., busid */
|
||||||
int unique_len; /* Length of unique field */
|
int unique_len; /* Length of unique field */
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*-
|
|
||||||
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
|
||||||
*/
|
|
||||||
/*-
|
|
||||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, 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
|
|
||||||
* VA LINUX SYSTEMS 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>
|
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "drmP.h"
|
|
||||||
|
|
||||||
int drm_adddraw(DRM_IOCTL_ARGS)
|
|
||||||
{
|
|
||||||
drm_draw_t draw;
|
|
||||||
|
|
||||||
draw.handle = 0; /* NOOP */
|
|
||||||
DRM_DEBUG("%d\n", draw.handle);
|
|
||||||
|
|
||||||
DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int drm_rmdraw(DRM_IOCTL_ARGS)
|
|
||||||
{
|
|
||||||
return 0; /* NOOP */
|
|
||||||
}
|
|
||||||
1
bsd-core/drm_drawable.c
Symbolic link
1
bsd-core/drm_drawable.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../shared-core/drm_drawable.c
|
||||||
|
|
@ -516,6 +516,9 @@ static int drm_load(drm_device_t *dev)
|
||||||
dev->pci_slot = pci_get_slot(dev->device);
|
dev->pci_slot = pci_get_slot(dev->device);
|
||||||
dev->pci_func = pci_get_function(dev->device);
|
dev->pci_func = pci_get_function(dev->device);
|
||||||
|
|
||||||
|
dev->pci_vendor = pci_get_vendor(dev->device);
|
||||||
|
dev->pci_device = pci_get_device(dev->device);
|
||||||
|
|
||||||
TAILQ_INIT(&dev->maplist);
|
TAILQ_INIT(&dev->maplist);
|
||||||
|
|
||||||
drm_mem_init();
|
drm_mem_init();
|
||||||
|
|
|
||||||
|
|
@ -1397,6 +1397,22 @@ int drmDestroyDrawable(int fd, drm_drawable_t handle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
|
||||||
|
drm_drawable_info_type_t type, unsigned int num,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
drm_update_draw_t update;
|
||||||
|
|
||||||
|
update.handle = handle;
|
||||||
|
update.type = type;
|
||||||
|
update.num = num;
|
||||||
|
update.data = (unsigned long long)(unsigned long)data;
|
||||||
|
|
||||||
|
if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire the AGP device.
|
* Acquire the AGP device.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,8 @@ typedef enum {
|
||||||
DRM_PAGE_ALIGN = 0x01,
|
DRM_PAGE_ALIGN = 0x01,
|
||||||
DRM_AGP_BUFFER = 0x02,
|
DRM_AGP_BUFFER = 0x02,
|
||||||
DRM_SG_BUFFER = 0x04,
|
DRM_SG_BUFFER = 0x04,
|
||||||
DRM_FB_BUFFER = 0x08
|
DRM_FB_BUFFER = 0x08,
|
||||||
|
DRM_PCI_BUFFER_RO = 0x10
|
||||||
} drmBufDescFlags;
|
} drmBufDescFlags;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -252,6 +253,8 @@ typedef struct _drmTextureRegion {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||||
DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
||||||
|
DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
|
||||||
|
DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
|
||||||
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
|
DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */
|
||||||
} drmVBlankSeqType;
|
} drmVBlankSeqType;
|
||||||
|
|
||||||
|
|
@ -544,6 +547,9 @@ extern int drmSwitchToContext(int fd, drm_context_t context);
|
||||||
extern int drmDestroyContext(int fd, drm_context_t handle);
|
extern int drmDestroyContext(int fd, drm_context_t handle);
|
||||||
extern int drmCreateDrawable(int fd, drm_drawable_t * handle);
|
extern int drmCreateDrawable(int fd, drm_drawable_t * handle);
|
||||||
extern int drmDestroyDrawable(int fd, drm_drawable_t handle);
|
extern int drmDestroyDrawable(int fd, drm_drawable_t handle);
|
||||||
|
extern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
|
||||||
|
drm_drawable_info_type_t type,
|
||||||
|
unsigned int num, void *data);
|
||||||
extern int drmCtlInstHandler(int fd, int irq);
|
extern int drmCtlInstHandler(int fd, int irq);
|
||||||
extern int drmCtlUninstHandler(int fd);
|
extern int drmCtlUninstHandler(int fd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ DRM_MODULES ?= $(MODULE_LIST)
|
||||||
|
|
||||||
# These definitions are for handling dependencies in the out of kernel build.
|
# These definitions are for handling dependencies in the out of kernel build.
|
||||||
|
|
||||||
DRMSHARED = drm.h drm_sarea.h
|
DRMSHARED = drm.h drm_sarea.h drm_drawable.c
|
||||||
DRMHEADERS = drmP.h drm_compat.h drm_os_linux.h $(DRMSHARED)
|
DRMHEADERS = drmP.h drm_compat.h drm_os_linux.h drm.h drm_sarea.h
|
||||||
COREHEADERS = drm_core.h drm_sman.h drm_hashtab.h
|
COREHEADERS = drm_core.h drm_sman.h drm_hashtab.h
|
||||||
|
|
||||||
TDFXHEADERS = tdfx_drv.h $(DRMHEADERS)
|
TDFXHEADERS = tdfx_drv.h $(DRMHEADERS)
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@
|
||||||
#define DRIVER_IRQ_VBL 0x100
|
#define DRIVER_IRQ_VBL 0x100
|
||||||
#define DRIVER_DMA_QUEUE 0x200
|
#define DRIVER_DMA_QUEUE 0x200
|
||||||
#define DRIVER_FB_DMA 0x400
|
#define DRIVER_FB_DMA 0x400
|
||||||
|
#define DRIVER_IRQ_VBL2 0x800
|
||||||
|
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
@ -448,7 +449,8 @@ typedef struct drm_device_dma {
|
||||||
enum {
|
enum {
|
||||||
_DRM_DMA_USE_AGP = 0x01,
|
_DRM_DMA_USE_AGP = 0x01,
|
||||||
_DRM_DMA_USE_SG = 0x02,
|
_DRM_DMA_USE_SG = 0x02,
|
||||||
_DRM_DMA_USE_FB = 0x04
|
_DRM_DMA_USE_FB = 0x04,
|
||||||
|
_DRM_DMA_USE_PCI_RO = 0x08
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
} drm_device_dma_t;
|
} drm_device_dma_t;
|
||||||
|
|
@ -582,6 +584,7 @@ struct drm_driver {
|
||||||
int new);
|
int new);
|
||||||
void (*kernel_context_switch_unlock) (struct drm_device * dev);
|
void (*kernel_context_switch_unlock) (struct drm_device * dev);
|
||||||
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
|
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
|
||||||
|
int (*vblank_wait2) (struct drm_device * dev, unsigned int *sequence);
|
||||||
int (*dri_library_name) (struct drm_device * dev, char * buf);
|
int (*dri_library_name) (struct drm_device * dev, char * buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -732,9 +735,13 @@ typedef struct drm_device {
|
||||||
|
|
||||||
wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
|
wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
|
||||||
atomic_t vbl_received;
|
atomic_t vbl_received;
|
||||||
|
atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
|
||||||
spinlock_t vbl_lock;
|
spinlock_t vbl_lock;
|
||||||
drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
|
drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
|
||||||
|
drm_vbl_sig_t vbl_sigs2; /**< signals to send on secondary VBLANK */
|
||||||
unsigned int vbl_pending;
|
unsigned int vbl_pending;
|
||||||
|
spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
|
||||||
|
void (*locked_tasklet_func)(struct drm_device *dev);
|
||||||
|
|
||||||
/*@} */
|
/*@} */
|
||||||
cycles_t ctx_start;
|
cycles_t ctx_start;
|
||||||
|
|
@ -747,6 +754,8 @@ typedef struct drm_device {
|
||||||
drm_agp_head_t *agp; /**< AGP data */
|
drm_agp_head_t *agp; /**< AGP data */
|
||||||
|
|
||||||
struct pci_dev *pdev; /**< PCI device structure */
|
struct pci_dev *pdev; /**< PCI device structure */
|
||||||
|
int pci_vendor; /**< PCI vendor id */
|
||||||
|
int pci_device; /**< PCI device id */
|
||||||
#ifdef __alpha__
|
#ifdef __alpha__
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
|
||||||
struct pci_controler *hose;
|
struct pci_controler *hose;
|
||||||
|
|
@ -764,6 +773,15 @@ typedef struct drm_device {
|
||||||
drm_local_map_t *agp_buffer_map;
|
drm_local_map_t *agp_buffer_map;
|
||||||
unsigned int agp_buffer_token;
|
unsigned int agp_buffer_token;
|
||||||
drm_head_t primary; /**< primary screen head */
|
drm_head_t primary; /**< primary screen head */
|
||||||
|
|
||||||
|
/** \name Drawable information */
|
||||||
|
/*@{ */
|
||||||
|
spinlock_t drw_lock;
|
||||||
|
unsigned int drw_bitfield_length;
|
||||||
|
u32 *drw_bitfield;
|
||||||
|
unsigned int drw_info_length;
|
||||||
|
drm_drawable_info_t **drw_info;
|
||||||
|
/*@} */
|
||||||
} drm_device_t;
|
} drm_device_t;
|
||||||
|
|
||||||
static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
||||||
|
|
@ -775,7 +793,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
||||||
#ifdef __alpha__
|
#ifdef __alpha__
|
||||||
#define drm_get_pci_domain(dev) dev->hose->bus->number
|
#define drm_get_pci_domain(dev) dev->hose->bus->number
|
||||||
#else
|
#else
|
||||||
#define drm_get_pci_domain(dev) pci_domain_nr(dev->pdev->bus)
|
#define drm_get_pci_domain(dev) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
|
|
@ -808,6 +826,18 @@ static inline int drm_mtrr_del(int handle, unsigned long offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int drm_mtrr_del(int handle, unsigned long offset,
|
||||||
|
unsigned long size, unsigned int flags)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
#define drm_core_has_MTRR(dev) (0)
|
#define drm_core_has_MTRR(dev) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -902,6 +932,10 @@ extern int drm_adddraw(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
extern int drm_rmdraw(struct inode *inode, struct file *filp,
|
extern int drm_rmdraw(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
|
extern int drm_update_drawable_info(struct inode *inode, struct file *filp,
|
||||||
|
unsigned int cmd, unsigned long arg);
|
||||||
|
extern drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev,
|
||||||
|
drm_drawable_t id);
|
||||||
|
|
||||||
/* Authentication IOCTL support (drm_auth.h) */
|
/* Authentication IOCTL support (drm_auth.h) */
|
||||||
extern int drm_getmagic(struct inode *inode, struct file *filp,
|
extern int drm_getmagic(struct inode *inode, struct file *filp,
|
||||||
|
|
@ -966,6 +1000,7 @@ extern int drm_wait_vblank(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
|
extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
|
||||||
extern void drm_vbl_send_signals(drm_device_t * dev);
|
extern void drm_vbl_send_signals(drm_device_t * dev);
|
||||||
|
extern void drm_locked_tasklet(drm_device_t *dev, void(*func)(drm_device_t*));
|
||||||
|
|
||||||
/* AGP/GART support (drm_agpsupport.h) */
|
/* AGP/GART support (drm_agpsupport.h) */
|
||||||
extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
|
extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
|
||||||
|
|
|
||||||
|
|
@ -942,6 +942,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
|
||||||
request->count = entry->buf_count;
|
request->count = entry->buf_count;
|
||||||
request->size = size;
|
request->size = size;
|
||||||
|
|
||||||
|
if (request->flags & _DRM_PCI_BUFFER_RO)
|
||||||
|
dma->flags = _DRM_DMA_USE_PCI_RO;
|
||||||
|
|
||||||
atomic_dec(&dev->buf_alloc);
|
atomic_dec(&dev->buf_alloc);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1528,9 +1531,10 @@ int drm_freebufs(struct inode *inode, struct file *filp,
|
||||||
* \param arg pointer to a drm_buf_map structure.
|
* \param arg pointer to a drm_buf_map structure.
|
||||||
* \return zero on success or a negative number on failure.
|
* \return zero on success or a negative number on failure.
|
||||||
*
|
*
|
||||||
* Maps the AGP or SG buffer region with do_mmap(), and copies information
|
* Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
|
||||||
* about each buffer into user space. The PCI buffers are already mapped on the
|
* about each buffer into user space. For PCI buffers, it calls do_mmap() with
|
||||||
* addbufs_pci() call.
|
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
|
||||||
|
* drm_mmap_dma().
|
||||||
*/
|
*/
|
||||||
int drm_mapbufs(struct inode *inode, struct file *filp,
|
int drm_mapbufs(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
#define CORE_NAME "drm"
|
#define CORE_NAME "drm"
|
||||||
#define CORE_DESC "DRM shared core routines"
|
#define CORE_DESC "DRM shared core routines"
|
||||||
#define CORE_DATE "20051102"
|
#define CORE_DATE "20060810"
|
||||||
|
|
||||||
#define DRM_IF_MAJOR 1
|
#define DRM_IF_MAJOR 1
|
||||||
#define DRM_IF_MINOR 2
|
#define DRM_IF_MINOR 3
|
||||||
|
|
||||||
#define CORE_MAJOR 1
|
#define CORE_MAJOR 1
|
||||||
#define CORE_MINOR 0
|
#define CORE_MINOR 1
|
||||||
#define CORE_PATCHLEVEL 1
|
#define CORE_PATCHLEVEL 0
|
||||||
|
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
/**
|
|
||||||
* \file drm_drawable.c
|
|
||||||
* IOCTLs for drawables
|
|
||||||
*
|
|
||||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
|
||||||
* \author Gareth Hughes <gareth@valinux.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
|
||||||
*
|
|
||||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, 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
|
|
||||||
* VA LINUX SYSTEMS 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "drmP.h"
|
|
||||||
|
|
||||||
/** No-op. */
|
|
||||||
int drm_adddraw(struct inode *inode, struct file *filp,
|
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
|
||||||
drm_draw_t draw;
|
|
||||||
|
|
||||||
draw.handle = 0; /* NOOP */
|
|
||||||
DRM_DEBUG("%d\n", draw.handle);
|
|
||||||
if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw)))
|
|
||||||
return -EFAULT;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** No-op. */
|
|
||||||
int drm_rmdraw(struct inode *inode, struct file *filp,
|
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
|
||||||
return 0; /* NOOP */
|
|
||||||
}
|
|
||||||
1
linux-core/drm_drawable.c
Symbolic link
1
linux-core/drm_drawable.c
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../shared-core/drm_drawable.c
|
||||||
|
|
@ -119,6 +119,8 @@ static drm_ioctl_desc_t drm_ioctls[] = {
|
||||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||||
|
|
||||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
|
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
|
||||||
|
|
||||||
|
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
|
#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
|
||||||
|
|
@ -154,6 +156,18 @@ int drm_lastclose(drm_device_t * dev)
|
||||||
if (dev->irq_enabled)
|
if (dev->irq_enabled)
|
||||||
drm_irq_uninstall(dev);
|
drm_irq_uninstall(dev);
|
||||||
|
|
||||||
|
/* Free drawable information memory */
|
||||||
|
for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield);
|
||||||
|
i++) {
|
||||||
|
drm_drawable_info_t *info = drm_get_drawable_info(dev, i);
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
drm_free(info->rects, info->num_rects *
|
||||||
|
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||||
|
drm_free(info, sizeof(*info), DRM_MEM_BUFS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
del_timer(&dev->timer);
|
del_timer(&dev->timer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ static int drm_irq_install(drm_device_t * dev)
|
||||||
spin_lock_init(&dev->vbl_lock);
|
spin_lock_init(&dev->vbl_lock);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dev->vbl_sigs.head);
|
INIT_LIST_HEAD(&dev->vbl_sigs.head);
|
||||||
|
INIT_LIST_HEAD(&dev->vbl_sigs2.head);
|
||||||
|
|
||||||
dev->vbl_pending = 0;
|
dev->vbl_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +175,8 @@ int drm_irq_uninstall(drm_device_t * dev)
|
||||||
|
|
||||||
free_irq(dev->irq, dev);
|
free_irq(dev->irq, dev);
|
||||||
|
|
||||||
|
dev->locked_tasklet_func = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_irq_uninstall);
|
EXPORT_SYMBOL(drm_irq_uninstall);
|
||||||
|
|
@ -245,10 +248,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
drm_wait_vblank_t vblwait;
|
drm_wait_vblank_t vblwait;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int flags;
|
unsigned int flags, seq;
|
||||||
|
|
||||||
if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if ((!dev->irq) || (!dev->irq_enabled))
|
if ((!dev->irq) || (!dev->irq_enabled))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -256,9 +256,26 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
if (copy_from_user(&vblwait, argp, sizeof(vblwait)))
|
if (copy_from_user(&vblwait, argp, sizeof(vblwait)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
|
if (vblwait.request.type &
|
||||||
|
~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
|
||||||
|
DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
|
||||||
|
vblwait.request.type,
|
||||||
|
(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
|
||||||
|
|
||||||
|
if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
|
||||||
|
DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
|
||||||
|
: &dev->vbl_received);
|
||||||
|
|
||||||
|
switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
|
||||||
case _DRM_VBLANK_RELATIVE:
|
case _DRM_VBLANK_RELATIVE:
|
||||||
vblwait.request.sequence += atomic_read(&dev->vbl_received);
|
vblwait.request.sequence += seq;
|
||||||
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||||
case _DRM_VBLANK_ABSOLUTE:
|
case _DRM_VBLANK_ABSOLUTE:
|
||||||
break;
|
break;
|
||||||
|
|
@ -266,26 +283,30 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
|
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
|
||||||
|
(seq - vblwait.request.sequence) <= (1<<23)) {
|
||||||
|
vblwait.request.sequence = seq + 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & _DRM_VBLANK_SIGNAL) {
|
if (flags & _DRM_VBLANK_SIGNAL) {
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
drm_vbl_sig_t *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
|
||||||
|
? &dev->vbl_sigs2 : &dev->vbl_sigs;
|
||||||
drm_vbl_sig_t *vbl_sig;
|
drm_vbl_sig_t *vbl_sig;
|
||||||
|
|
||||||
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||||
|
|
||||||
/* Check if this task has already scheduled the same signal
|
/* Check if this task has already scheduled the same signal
|
||||||
* for the same vblank sequence number; nothing to be done in
|
* for the same vblank sequence number; nothing to be done in
|
||||||
* that case
|
* that case
|
||||||
*/
|
*/
|
||||||
list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) {
|
list_for_each_entry(vbl_sig, &vbl_sigs->head, head) {
|
||||||
if (vbl_sig->sequence == vblwait.request.sequence
|
if (vbl_sig->sequence == vblwait.request.sequence
|
||||||
&& vbl_sig->info.si_signo == vblwait.request.signal
|
&& vbl_sig->info.si_signo == vblwait.request.signal
|
||||||
&& vbl_sig->task == current) {
|
&& vbl_sig->task == current) {
|
||||||
spin_unlock_irqrestore(&dev->vbl_lock,
|
spin_unlock_irqrestore(&dev->vbl_lock,
|
||||||
irqflags);
|
irqflags);
|
||||||
|
vblwait.reply.sequence = seq;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -313,11 +334,16 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||||
|
|
||||||
list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head);
|
list_add_tail((struct list_head *)vbl_sig, &vbl_sigs->head);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||||
|
|
||||||
|
vblwait.reply.sequence = seq;
|
||||||
} else {
|
} else {
|
||||||
if (dev->driver->vblank_wait)
|
if (flags & _DRM_VBLANK_SECONDARY) {
|
||||||
|
if (dev->driver->vblank_wait2)
|
||||||
|
ret = dev->driver->vblank_wait2(dev, &vblwait.request.sequence);
|
||||||
|
} else if (dev->driver->vblank_wait)
|
||||||
ret =
|
ret =
|
||||||
dev->driver->vblank_wait(dev,
|
dev->driver->vblank_wait(dev,
|
||||||
&vblwait.request.sequence);
|
&vblwait.request.sequence);
|
||||||
|
|
@ -345,28 +371,109 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||||
*/
|
*/
|
||||||
void drm_vbl_send_signals(drm_device_t * dev)
|
void drm_vbl_send_signals(drm_device_t * dev)
|
||||||
{
|
{
|
||||||
struct list_head *list, *tmp;
|
|
||||||
drm_vbl_sig_t *vbl_sig;
|
|
||||||
unsigned int vbl_seq = atomic_read(&dev->vbl_received);
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->vbl_lock, flags);
|
spin_lock_irqsave(&dev->vbl_lock, flags);
|
||||||
|
|
||||||
list_for_each_safe(list, tmp, &dev->vbl_sigs.head) {
|
for (i = 0; i < 2; i++) {
|
||||||
vbl_sig = list_entry(list, drm_vbl_sig_t, head);
|
struct list_head *list, *tmp;
|
||||||
if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
|
drm_vbl_sig_t *vbl_sig;
|
||||||
vbl_sig->info.si_code = vbl_seq;
|
drm_vbl_sig_t *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
|
||||||
send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info,
|
unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
|
||||||
vbl_sig->task);
|
&dev->vbl_received);
|
||||||
|
|
||||||
list_del(list);
|
list_for_each_safe(list, tmp, &vbl_sigs->head) {
|
||||||
|
vbl_sig = list_entry(list, drm_vbl_sig_t, head);
|
||||||
|
if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
|
||||||
|
vbl_sig->info.si_code = vbl_seq;
|
||||||
|
send_sig_info(vbl_sig->info.si_signo,
|
||||||
|
&vbl_sig->info, vbl_sig->task);
|
||||||
|
|
||||||
drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER);
|
list_del(list);
|
||||||
|
|
||||||
dev->vbl_pending--;
|
drm_free(vbl_sig, sizeof(*vbl_sig),
|
||||||
|
DRM_MEM_DRIVER);
|
||||||
|
|
||||||
|
dev->vbl_pending--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev->vbl_lock, flags);
|
spin_unlock_irqrestore(&dev->vbl_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_vbl_send_signals);
|
EXPORT_SYMBOL(drm_vbl_send_signals);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tasklet wrapper function.
|
||||||
|
*
|
||||||
|
* \param data DRM device in disguise.
|
||||||
|
*
|
||||||
|
* Attempts to grab the HW lock and calls the driver callback on success. On
|
||||||
|
* failure, leave the lock marked as contended so the callback can be called
|
||||||
|
* from drm_unlock().
|
||||||
|
*/
|
||||||
|
static void drm_locked_tasklet_func(unsigned long data)
|
||||||
|
{
|
||||||
|
drm_device_t *dev = (drm_device_t*)data;
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
|
||||||
|
|
||||||
|
if (!dev->locked_tasklet_func ||
|
||||||
|
!drm_lock_take(&dev->lock.hw_lock->lock,
|
||||||
|
DRM_KERNEL_CONTEXT)) {
|
||||||
|
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->lock.lock_time = jiffies;
|
||||||
|
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||||
|
|
||||||
|
dev->locked_tasklet_func(dev);
|
||||||
|
|
||||||
|
drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||||
|
DRM_KERNEL_CONTEXT);
|
||||||
|
|
||||||
|
dev->locked_tasklet_func = NULL;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule a tasklet to call back a driver hook with the HW lock held.
|
||||||
|
*
|
||||||
|
* \param dev DRM device.
|
||||||
|
* \param func Driver callback.
|
||||||
|
*
|
||||||
|
* This is intended for triggering actions that require the HW lock from an
|
||||||
|
* interrupt handler. The lock will be grabbed ASAP after the interrupt handler
|
||||||
|
* completes. Note that the callback may be called from interrupt or process
|
||||||
|
* context, it must not make any assumptions about this. Also, the HW lock will
|
||||||
|
* be held with the kernel context or any client context.
|
||||||
|
*/
|
||||||
|
void drm_locked_tasklet(drm_device_t *dev, void (*func)(drm_device_t*))
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0);
|
||||||
|
|
||||||
|
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) ||
|
||||||
|
test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
|
||||||
|
|
||||||
|
if (dev->locked_tasklet_func) {
|
||||||
|
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->locked_tasklet_func = func;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
|
||||||
|
|
||||||
|
drm_tasklet.data = (unsigned long)dev;
|
||||||
|
|
||||||
|
tasklet_hi_schedule(&drm_tasklet);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_locked_tasklet);
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
|
||||||
drm_file_t *priv = filp->private_data;
|
drm_file_t *priv = filp->private_data;
|
||||||
drm_device_t *dev = priv->head->dev;
|
drm_device_t *dev = priv->head->dev;
|
||||||
drm_lock_t lock;
|
drm_lock_t lock;
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
@ -162,6 +163,16 @@ int drm_unlock(struct inode *inode, struct file *filp,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
|
||||||
|
|
||||||
|
if (dev->locked_tasklet_func) {
|
||||||
|
dev->locked_tasklet_func(dev);
|
||||||
|
|
||||||
|
dev->locked_tasklet_func = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
|
||||||
|
|
||||||
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
|
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
|
||||||
|
|
||||||
/* kernel_context_switch isn't used by any of the x86 drm
|
/* kernel_context_switch isn't used by any of the x86 drm
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,15 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
spin_lock_init(&dev->count_lock);
|
spin_lock_init(&dev->count_lock);
|
||||||
|
spin_lock_init(&dev->drw_lock);
|
||||||
|
spin_lock_init(&dev->tasklet_lock);
|
||||||
init_timer(&dev->timer);
|
init_timer(&dev->timer);
|
||||||
mutex_init(&dev->struct_mutex);
|
mutex_init(&dev->struct_mutex);
|
||||||
mutex_init(&dev->ctxlist_mutex);
|
mutex_init(&dev->ctxlist_mutex);
|
||||||
|
|
||||||
dev->pdev = pdev;
|
dev->pdev = pdev;
|
||||||
|
dev->pci_device = pdev->device;
|
||||||
|
dev->pci_vendor = pdev->vendor;
|
||||||
|
|
||||||
#ifdef __alpha__
|
#ifdef __alpha__
|
||||||
dev->hose = pdev->sysdata;
|
dev->hose = pdev->sysdata;
|
||||||
|
|
|
||||||
|
|
@ -506,6 +506,22 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_ADMIN) &&
|
||||||
|
(dma->flags & _DRM_DMA_USE_PCI_RO)) {
|
||||||
|
vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
|
||||||
|
#else
|
||||||
|
/* Ye gads this is ugly. With more thought
|
||||||
|
we could move this up higher and use
|
||||||
|
`protection_map' instead. */
|
||||||
|
vma->vm_page_prot =
|
||||||
|
__pgprot(pte_val
|
||||||
|
(pte_wrprotect
|
||||||
|
(__pte(pgprot_val(vma->vm_page_prot)))));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
vma->vm_ops = &drm_vm_dma_ops;
|
vma->vm_ops = &drm_vm_dma_ops;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
|
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,14 @@ static struct drm_driver driver = {
|
||||||
*/
|
*/
|
||||||
.driver_features =
|
.driver_features =
|
||||||
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
|
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
|
||||||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
|
||||||
|
DRIVER_IRQ_VBL2,
|
||||||
.load = i915_driver_load,
|
.load = i915_driver_load,
|
||||||
.lastclose = i915_driver_lastclose,
|
.lastclose = i915_driver_lastclose,
|
||||||
.preclose = i915_driver_preclose,
|
.preclose = i915_driver_preclose,
|
||||||
.device_is_agp = i915_driver_device_is_agp,
|
.device_is_agp = i915_driver_device_is_agp,
|
||||||
.vblank_wait = i915_driver_vblank_wait,
|
.vblank_wait = i915_driver_vblank_wait,
|
||||||
|
.vblank_wait2 = i915_driver_vblank_wait2,
|
||||||
.irq_preinstall = i915_driver_irq_preinstall,
|
.irq_preinstall = i915_driver_irq_preinstall,
|
||||||
.irq_postinstall = i915_driver_irq_postinstall,
|
.irq_postinstall = i915_driver_irq_postinstall,
|
||||||
.irq_uninstall = i915_driver_irq_uninstall,
|
.irq_uninstall = i915_driver_irq_uninstall,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ module_param_named(no_wb, radeon_no_wb, int, 0444);
|
||||||
static int dri_library_name(struct drm_device * dev, char * buf)
|
static int dri_library_name(struct drm_device * dev, char * buf)
|
||||||
{
|
{
|
||||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
int family = dev_priv->flags & CHIP_FAMILY_MASK;
|
int family = dev_priv->flags & RADEON_FAMILY_MASK;
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||||
(family < CHIP_R200) ? "radeon" :
|
(family < CHIP_R200) ? "radeon" :
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,14 @@ typedef struct drm_clip_rect {
|
||||||
unsigned short y2;
|
unsigned short y2;
|
||||||
} drm_clip_rect_t;
|
} drm_clip_rect_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawable information.
|
||||||
|
*/
|
||||||
|
typedef struct drm_drawable_info {
|
||||||
|
unsigned int num_rects;
|
||||||
|
drm_clip_rect_t *rects;
|
||||||
|
} drm_drawable_info_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Texture region,
|
* Texture region,
|
||||||
*/
|
*/
|
||||||
|
|
@ -408,7 +416,8 @@ typedef struct drm_buf_desc {
|
||||||
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
|
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
|
||||||
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
|
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
|
||||||
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
|
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
|
||||||
_DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
|
_DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
|
||||||
|
_DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
|
||||||
} flags;
|
} flags;
|
||||||
unsigned long agp_start; /**<
|
unsigned long agp_start; /**<
|
||||||
* Start address of where the AGP buffers are
|
* Start address of where the AGP buffers are
|
||||||
|
|
@ -507,6 +516,20 @@ typedef struct drm_draw {
|
||||||
drm_drawable_t handle;
|
drm_drawable_t handle;
|
||||||
} drm_draw_t;
|
} drm_draw_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRM_IOCTL_UPDATE_DRAW ioctl argument type.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
DRM_DRAWABLE_CLIPRECTS,
|
||||||
|
} drm_drawable_info_type_t;
|
||||||
|
|
||||||
|
typedef struct drm_update_draw {
|
||||||
|
drm_drawable_t handle;
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int num;
|
||||||
|
unsigned long long data;
|
||||||
|
} drm_update_draw_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
|
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
|
||||||
*/
|
*/
|
||||||
|
|
@ -529,10 +552,14 @@ typedef struct drm_irq_busid {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||||
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
||||||
|
_DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
|
||||||
|
_DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
|
||||||
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
||||||
} drm_vblank_seq_type_t;
|
} drm_vblank_seq_type_t;
|
||||||
|
|
||||||
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
|
#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
|
||||||
|
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
|
||||||
|
_DRM_VBLANK_NEXTONMISS)
|
||||||
|
|
||||||
struct drm_wait_vblank_request {
|
struct drm_wait_vblank_request {
|
||||||
drm_vblank_seq_type_t type;
|
drm_vblank_seq_type_t type;
|
||||||
|
|
@ -694,6 +721,8 @@ typedef struct drm_set_version {
|
||||||
|
|
||||||
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
|
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t)
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
330
shared-core/drm_drawable.c
Normal file
330
shared-core/drm_drawable.c
Normal file
|
|
@ -0,0 +1,330 @@
|
||||||
|
/**
|
||||||
|
* \file drm_drawable.c
|
||||||
|
* IOCTLs for drawables
|
||||||
|
*
|
||||||
|
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||||
|
* \author Gareth Hughes <gareth@valinux.com>
|
||||||
|
* \author Michel Dänzer <michel@tungstengraphics.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
|
||||||
|
*
|
||||||
|
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||||
|
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota.
|
||||||
|
* 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
|
||||||
|
* VA LINUX SYSTEMS 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "drmP.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate drawable ID and memory to store information about it.
|
||||||
|
*/
|
||||||
|
int drm_adddraw(DRM_IOCTL_ARGS)
|
||||||
|
{
|
||||||
|
DRM_DEVICE;
|
||||||
|
unsigned long irqflags;
|
||||||
|
int i, j;
|
||||||
|
u32 *bitfield = dev->drw_bitfield;
|
||||||
|
unsigned int bitfield_length = dev->drw_bitfield_length;
|
||||||
|
drm_drawable_info_t **info = dev->drw_info;
|
||||||
|
unsigned int info_length = dev->drw_info_length;
|
||||||
|
drm_draw_t draw;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < bitfield_length; i++) {
|
||||||
|
if (bitfield[i] == ~0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (; j < 8 * sizeof(*bitfield); j++)
|
||||||
|
if (!(bitfield[i] & (1 << j)))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
|
||||||
|
if (i == bitfield_length) {
|
||||||
|
bitfield_length++;
|
||||||
|
|
||||||
|
bitfield = drm_alloc(bitfield_length * sizeof(*bitfield),
|
||||||
|
DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
if (!bitfield) {
|
||||||
|
DRM_ERROR("Failed to allocate new drawable bitfield\n");
|
||||||
|
return DRM_ERR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (8 * sizeof(*bitfield) * bitfield_length > info_length) {
|
||||||
|
info_length += 8 * sizeof(*bitfield);
|
||||||
|
|
||||||
|
info = drm_alloc(info_length * sizeof(*info),
|
||||||
|
DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
DRM_ERROR("Failed to allocate new drawable info"
|
||||||
|
" array\n");
|
||||||
|
|
||||||
|
drm_free(bitfield,
|
||||||
|
bitfield_length * sizeof(*bitfield),
|
||||||
|
DRM_MEM_BUFS);
|
||||||
|
return DRM_ERR(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitfield[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.handle = i * 8 * sizeof(*bitfield) + j + 1;
|
||||||
|
DRM_DEBUG("%d\n", draw.handle);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
bitfield[i] |= 1 << j;
|
||||||
|
info[draw.handle - 1] = NULL;
|
||||||
|
|
||||||
|
if (bitfield != dev->drw_bitfield) {
|
||||||
|
memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length *
|
||||||
|
sizeof(*bitfield));
|
||||||
|
drm_free(dev->drw_bitfield, sizeof(*bitfield) *
|
||||||
|
dev->drw_bitfield_length, DRM_MEM_BUFS);
|
||||||
|
dev->drw_bitfield = bitfield;
|
||||||
|
dev->drw_bitfield_length = bitfield_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info != dev->drw_info) {
|
||||||
|
memcpy(info, dev->drw_info, dev->drw_info_length *
|
||||||
|
sizeof(*info));
|
||||||
|
drm_free(dev->drw_info, sizeof(*info) * dev->drw_info_length,
|
||||||
|
DRM_MEM_BUFS);
|
||||||
|
dev->drw_info = info;
|
||||||
|
dev->drw_info_length = info_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
DRM_COPY_TO_USER_IOCTL((drm_draw_t __user *)data, draw, sizeof(draw));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free drawable ID and memory to store information about it.
|
||||||
|
*/
|
||||||
|
int drm_rmdraw(DRM_IOCTL_ARGS)
|
||||||
|
{
|
||||||
|
DRM_DEVICE;
|
||||||
|
drm_draw_t draw;
|
||||||
|
int id, idx;
|
||||||
|
unsigned int shift;
|
||||||
|
unsigned long irqflags;
|
||||||
|
u32 *bitfield = dev->drw_bitfield;
|
||||||
|
unsigned int bitfield_length = dev->drw_bitfield_length;
|
||||||
|
drm_drawable_info_t **info = dev->drw_info;
|
||||||
|
unsigned int info_length = dev->drw_info_length;
|
||||||
|
|
||||||
|
DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
|
||||||
|
sizeof(draw));
|
||||||
|
|
||||||
|
id = draw.handle - 1;
|
||||||
|
idx = id / (8 * sizeof(*bitfield));
|
||||||
|
shift = id % (8 * sizeof(*bitfield));
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= bitfield_length ||
|
||||||
|
!(bitfield[idx] & (1 << shift))) {
|
||||||
|
DRM_DEBUG("No such drawable %d\n", draw.handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
bitfield[idx] &= ~(1 << shift);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
if (info[id]) {
|
||||||
|
drm_free(info[id]->rects, info[id]->num_rects *
|
||||||
|
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||||
|
drm_free(info[id], sizeof(**info), DRM_MEM_BUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can we shrink the arrays? */
|
||||||
|
if (idx == bitfield_length - 1) {
|
||||||
|
while (idx >= 0 && !bitfield[idx])
|
||||||
|
--idx;
|
||||||
|
|
||||||
|
bitfield_length = idx + 1;
|
||||||
|
|
||||||
|
if (idx != id / (8 * sizeof(*bitfield)))
|
||||||
|
bitfield = drm_alloc(bitfield_length *
|
||||||
|
sizeof(*bitfield), DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
if (!bitfield && bitfield_length) {
|
||||||
|
bitfield = dev->drw_bitfield;
|
||||||
|
bitfield_length = dev->drw_bitfield_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitfield != dev->drw_bitfield) {
|
||||||
|
info_length = 8 * sizeof(*bitfield) * bitfield_length;
|
||||||
|
|
||||||
|
info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
if (!info && info_length) {
|
||||||
|
info = dev->drw_info;
|
||||||
|
info_length = dev->drw_info_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
memcpy(bitfield, dev->drw_bitfield, bitfield_length *
|
||||||
|
sizeof(*bitfield));
|
||||||
|
drm_free(dev->drw_bitfield, sizeof(*bitfield) *
|
||||||
|
dev->drw_bitfield_length, DRM_MEM_BUFS);
|
||||||
|
dev->drw_bitfield = bitfield;
|
||||||
|
dev->drw_bitfield_length = bitfield_length;
|
||||||
|
|
||||||
|
if (info != dev->drw_info) {
|
||||||
|
memcpy(info, dev->drw_info, info_length *
|
||||||
|
sizeof(*info));
|
||||||
|
drm_free(dev->drw_info, sizeof(*info) *
|
||||||
|
dev->drw_info_length, DRM_MEM_BUFS);
|
||||||
|
dev->drw_info = info;
|
||||||
|
dev->drw_info_length = info_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_DEBUG("%d\n", draw.handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drm_update_drawable_info(DRM_IOCTL_ARGS) {
|
||||||
|
DRM_DEVICE;
|
||||||
|
drm_update_draw_t update;
|
||||||
|
unsigned int id, idx, shift, bitfield_length = dev->drw_bitfield_length;
|
||||||
|
u32 *bitfield = dev->drw_bitfield;
|
||||||
|
unsigned long irqflags;
|
||||||
|
drm_drawable_info_t *info;
|
||||||
|
drm_clip_rect_t *rects;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
|
||||||
|
sizeof(update));
|
||||||
|
|
||||||
|
id = update.handle - 1;
|
||||||
|
idx = id / (8 * sizeof(*bitfield));
|
||||||
|
shift = id % (8 * sizeof(*bitfield));
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= bitfield_length ||
|
||||||
|
!(bitfield[idx] & (1 << shift))) {
|
||||||
|
DRM_ERROR("No such drawable %d\n", update.handle);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
info = dev->drw_info[id];
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
info = drm_calloc(1, sizeof(drm_drawable_info_t), DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
DRM_ERROR("Failed to allocate drawable info memory\n");
|
||||||
|
return DRM_ERR(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (update.type) {
|
||||||
|
case DRM_DRAWABLE_CLIPRECTS:
|
||||||
|
if (update.num != info->num_rects) {
|
||||||
|
rects = drm_alloc(update.num * sizeof(drm_clip_rect_t),
|
||||||
|
DRM_MEM_BUFS);
|
||||||
|
} else
|
||||||
|
rects = info->rects;
|
||||||
|
|
||||||
|
if (update.num && !rects) {
|
||||||
|
DRM_ERROR("Failed to allocate cliprect memory\n");
|
||||||
|
err = DRM_ERR(ENOMEM);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update.num && DRM_COPY_FROM_USER(rects,
|
||||||
|
(drm_clip_rect_t __user *)
|
||||||
|
(unsigned long)update.data,
|
||||||
|
update.num *
|
||||||
|
sizeof(*rects))) {
|
||||||
|
DRM_ERROR("Failed to copy cliprects from userspace\n");
|
||||||
|
err = DRM_ERR(EFAULT);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
if (rects != info->rects) {
|
||||||
|
drm_free(info->rects, info->num_rects *
|
||||||
|
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->rects = rects;
|
||||||
|
info->num_rects = update.num;
|
||||||
|
dev->drw_info[id] = info;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
DRM_DEBUG("Updated %d cliprects for drawable %d\n",
|
||||||
|
info->num_rects, id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_ERROR("Invalid update type %d\n", update.type);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (!dev->drw_info[id])
|
||||||
|
drm_free(info, sizeof(*info), DRM_MEM_BUFS);
|
||||||
|
else if (rects != dev->drw_info[id]->rects)
|
||||||
|
drm_free(rects, update.num *
|
||||||
|
sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caller must hold the drawable spinlock!
|
||||||
|
*/
|
||||||
|
drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
|
||||||
|
u32 *bitfield = dev->drw_bitfield;
|
||||||
|
unsigned int idx, shift;
|
||||||
|
|
||||||
|
id--;
|
||||||
|
idx = id / (8 * sizeof(*bitfield));
|
||||||
|
shift = id % (8 * sizeof(*bitfield));
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= dev->drw_bitfield_length ||
|
||||||
|
!(bitfield[idx] & (1 << shift))) {
|
||||||
|
DRM_DEBUG("No such drawable %d\n", id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev->drw_info[id];
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_drawable_info);
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
[radeon]
|
[radeon]
|
||||||
0x1002 0x3150 CHIP_RV380|CHIP_IS_MOBILITY "ATI Radeon Mobility X600 M24"
|
0x1002 0x3150 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 M24"
|
||||||
0x1002 0x3152 CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon Mobility X300 M24"
|
0x1002 0x3152 CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X300 M24"
|
||||||
0x1002 0x3154 CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI FireGL M24 GL"
|
0x1002 0x3154 CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI FireGL M24 GL"
|
||||||
0x1002 0x3E50 CHIP_RV380|CHIP_NEW_MEMMAP "ATI Radeon RV380 X600"
|
0x1002 0x3E50 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV380 X600"
|
||||||
0x1002 0x3E54 CHIP_RV380|CHIP_NEW_MEMMAP "ATI FireGL V3200 RV380"
|
0x1002 0x3E54 CHIP_RV380|RADEON_NEW_MEMMAP "ATI FireGL V3200 RV380"
|
||||||
0x1002 0x4136 CHIP_RS100|CHIP_IS_IGP "ATI Radeon RS100 IGP 320"
|
0x1002 0x4136 CHIP_RS100|RADEON_IS_IGP "ATI Radeon RS100 IGP 320"
|
||||||
0x1002 0x4137 CHIP_RS200|CHIP_IS_IGP "ATI Radeon RS200 IGP 340"
|
0x1002 0x4137 CHIP_RS200|RADEON_IS_IGP "ATI Radeon RS200 IGP 340"
|
||||||
0x1002 0x4144 CHIP_R300 "ATI Radeon AD 9500"
|
0x1002 0x4144 CHIP_R300 "ATI Radeon AD 9500"
|
||||||
0x1002 0x4145 CHIP_R300 "ATI Radeon AE 9700 Pro"
|
0x1002 0x4145 CHIP_R300 "ATI Radeon AE 9700 Pro"
|
||||||
0x1002 0x4146 CHIP_R300 "ATI Radeon AF R300 9600TX"
|
0x1002 0x4146 CHIP_R300 "ATI Radeon AF R300 9600TX"
|
||||||
|
|
@ -21,35 +21,35 @@
|
||||||
0x1002 0x4154 CHIP_RV350 "ATI FireGL AT T2"
|
0x1002 0x4154 CHIP_RV350 "ATI FireGL AT T2"
|
||||||
0x1002 0x4155 CHIP_RV350 "ATI Radeon 9650"
|
0x1002 0x4155 CHIP_RV350 "ATI Radeon 9650"
|
||||||
0x1002 0x4156 CHIP_RV350 "ATI FireGL AV RV360 T2"
|
0x1002 0x4156 CHIP_RV350 "ATI FireGL AV RV360 T2"
|
||||||
0x1002 0x4237 CHIP_RS200|CHIP_IS_IGP "ATI Radeon RS250 IGP"
|
0x1002 0x4237 CHIP_RS200|RADEON_IS_IGP "ATI Radeon RS250 IGP"
|
||||||
0x1002 0x4242 CHIP_R200 "ATI Radeon BB R200 AIW 8500DV"
|
0x1002 0x4242 CHIP_R200 "ATI Radeon BB R200 AIW 8500DV"
|
||||||
0x1002 0x4243 CHIP_R200 "ATI Radeon BC R200"
|
0x1002 0x4243 CHIP_R200 "ATI Radeon BC R200"
|
||||||
0x1002 0x4336 CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY "ATI Radeon RS100 Mobility U1"
|
0x1002 0x4336 CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS100 Mobility U1"
|
||||||
0x1002 0x4337 CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY "ATI Radeon RS200 Mobility IGP 340M"
|
0x1002 0x4337 CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS200 Mobility IGP 340M"
|
||||||
0x1002 0x4437 CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY "ATI Radeon RS250 Mobility IGP"
|
0x1002 0x4437 CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS250 Mobility IGP"
|
||||||
0x1002 0x4966 CHIP_RV250 "ATI Radeon If RV250 9000"
|
0x1002 0x4966 CHIP_RV250 "ATI Radeon If RV250 9000"
|
||||||
0x1002 0x4967 CHIP_RV250 "ATI Radeon Ig RV250 9000"
|
0x1002 0x4967 CHIP_RV250 "ATI Radeon Ig RV250 9000"
|
||||||
0x1002 0x4A48 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JH R420 X800"
|
0x1002 0x4A48 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JH R420 X800"
|
||||||
0x1002 0x4A49 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JI R420 X800 Pro"
|
0x1002 0x4A49 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JI R420 X800 Pro"
|
||||||
0x1002 0x4A4A CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JJ R420 X800 SE"
|
0x1002 0x4A4A CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JJ R420 X800 SE"
|
||||||
0x1002 0x4A4B CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JK R420 X800 XT"
|
0x1002 0x4A4B CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JK R420 X800 XT"
|
||||||
0x1002 0x4A4C CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JL R420 X800"
|
0x1002 0x4A4C CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JL R420 X800"
|
||||||
0x1002 0x4A4D CHIP_R420|CHIP_NEW_MEMMAP "ATI FireGL JM X3-256"
|
0x1002 0x4A4D CHIP_R420|RADEON_NEW_MEMMAP "ATI FireGL JM X3-256"
|
||||||
0x1002 0x4A4E CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon JN R420 Mobility M18"
|
0x1002 0x4A4E CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon JN R420 Mobility M18"
|
||||||
0x1002 0x4A4F CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JO R420 X800 SE"
|
0x1002 0x4A4F CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JO R420 X800 SE"
|
||||||
0x1002 0x4A50 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JP R420 X800 XT PE"
|
0x1002 0x4A50 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JP R420 X800 XT PE"
|
||||||
0x1002 0x4A54 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon JT R420 AIW X800 VE"
|
0x1002 0x4A54 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon JT R420 AIW X800 VE"
|
||||||
0x1002 0x4B49 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R481 X850 XT"
|
0x1002 0x4B49 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R481 X850 XT"
|
||||||
0x1002 0x4B4A CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R481 X850 SE"
|
0x1002 0x4B4A CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R481 X850 SE"
|
||||||
0x1002 0x4B4B CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R481 X850 Pro"
|
0x1002 0x4B4B CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R481 X850 Pro"
|
||||||
0x1002 0x4B4C CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R481 X850 XT PE"
|
0x1002 0x4B4C CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R481 X850 XT PE"
|
||||||
0x1002 0x4C57 CHIP_RV200|CHIP_IS_MOBILITY "ATI Radeon LW RV200 Mobility 7500 M7"
|
0x1002 0x4C57 CHIP_RV200|RADEON_IS_MOBILITY "ATI Radeon LW RV200 Mobility 7500 M7"
|
||||||
0x1002 0x4C58 CHIP_RV200|CHIP_IS_MOBILITY "ATI Radeon LX RV200 Mobility FireGL 7800 M7"
|
0x1002 0x4C58 CHIP_RV200|RADEON_IS_MOBILITY "ATI Radeon LX RV200 Mobility FireGL 7800 M7"
|
||||||
0x1002 0x4C59 CHIP_RV100|CHIP_IS_MOBILITY "ATI Radeon LY RV100 Mobility M6"
|
0x1002 0x4C59 CHIP_RV100|RADEON_IS_MOBILITY "ATI Radeon LY RV100 Mobility M6"
|
||||||
0x1002 0x4C5A CHIP_RV100|CHIP_IS_MOBILITY "ATI Radeon LZ RV100 Mobility M6"
|
0x1002 0x4C5A CHIP_RV100|RADEON_IS_MOBILITY "ATI Radeon LZ RV100 Mobility M6"
|
||||||
0x1002 0x4C64 CHIP_RV250|CHIP_IS_MOBILITY "ATI Radeon Ld RV250 Mobility 9000 M9"
|
0x1002 0x4C64 CHIP_RV250|RADEON_IS_MOBILITY "ATI Radeon Ld RV250 Mobility 9000 M9"
|
||||||
0x1002 0x4C66 CHIP_RV250 "ATI Radeon Lf RV250 Mobility 9000 M9 / FireMV 2400 PCI"
|
0x1002 0x4C66 CHIP_RV250 "ATI Radeon Lf RV250 Mobility 9000 M9 / FireMV 2400 PCI"
|
||||||
0x1002 0x4C67 CHIP_RV250|CHIP_IS_MOBILITY "ATI Radeon Lg RV250 Mobility 9000 M9"
|
0x1002 0x4C67 CHIP_RV250|RADEON_IS_MOBILITY "ATI Radeon Lg RV250 Mobility 9000 M9"
|
||||||
0x1002 0x4E44 CHIP_R300 "ATI Radeon ND R300 9700 Pro"
|
0x1002 0x4E44 CHIP_R300 "ATI Radeon ND R300 9700 Pro"
|
||||||
0x1002 0x4E45 CHIP_R300 "ATI Radeon NE R300 9500 Pro / 9700"
|
0x1002 0x4E45 CHIP_R300 "ATI Radeon NE R300 9500 Pro / 9700"
|
||||||
0x1002 0x4E46 CHIP_R300 "ATI Radeon NF R300 9600TX"
|
0x1002 0x4E46 CHIP_R300 "ATI Radeon NF R300 9600TX"
|
||||||
|
|
@ -58,16 +58,16 @@
|
||||||
0x1002 0x4E49 CHIP_R350 "ATI Radeon NI R350 9800"
|
0x1002 0x4E49 CHIP_R350 "ATI Radeon NI R350 9800"
|
||||||
0x1002 0x4E4A CHIP_R350 "ATI Radeon NJ R360 9800 XT"
|
0x1002 0x4E4A CHIP_R350 "ATI Radeon NJ R360 9800 XT"
|
||||||
0x1002 0x4E4B CHIP_R350 "ATI FireGL NK X2"
|
0x1002 0x4E4B CHIP_R350 "ATI FireGL NK X2"
|
||||||
0x1002 0x4E50 CHIP_RV350|CHIP_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NP"
|
0x1002 0x4E50 CHIP_RV350|RADEON_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NP"
|
||||||
0x1002 0x4E51 CHIP_RV350|CHIP_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NQ"
|
0x1002 0x4E51 CHIP_RV350|RADEON_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NQ"
|
||||||
0x1002 0x4E52 CHIP_RV350|CHIP_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M11 NR"
|
0x1002 0x4E52 CHIP_RV350|RADEON_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M11 NR"
|
||||||
0x1002 0x4E53 CHIP_RV350|CHIP_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NS"
|
0x1002 0x4E53 CHIP_RV350|RADEON_IS_MOBILITY "ATI Radeon RV350 Mobility 9600 M10 NS"
|
||||||
0x1002 0x4E54 CHIP_RV350|CHIP_IS_MOBILITY "ATI FireGL T2/T2e"
|
0x1002 0x4E54 CHIP_RV350|RADEON_IS_MOBILITY "ATI FireGL T2/T2e"
|
||||||
0x1002 0x4E56 CHIP_RV350|CHIP_IS_MOBILITY "ATI Radeon Mobility 9550"
|
0x1002 0x4E56 CHIP_RV350|RADEON_IS_MOBILITY "ATI Radeon Mobility 9550"
|
||||||
0x1002 0x5144 CHIP_R100|CHIP_SINGLE_CRTC "ATI Radeon QD R100"
|
0x1002 0x5144 CHIP_R100|RADEON_SINGLE_CRTC "ATI Radeon QD R100"
|
||||||
0x1002 0x5145 CHIP_R100|CHIP_SINGLE_CRTC "ATI Radeon QE R100"
|
0x1002 0x5145 CHIP_R100|RADEON_SINGLE_CRTC "ATI Radeon QE R100"
|
||||||
0x1002 0x5146 CHIP_R100|CHIP_SINGLE_CRTC "ATI Radeon QF R100"
|
0x1002 0x5146 CHIP_R100|RADEON_SINGLE_CRTC "ATI Radeon QF R100"
|
||||||
0x1002 0x5147 CHIP_R100|CHIP_SINGLE_CRTC "ATI Radeon QG R100"
|
0x1002 0x5147 CHIP_R100|RADEON_SINGLE_CRTC "ATI Radeon QG R100"
|
||||||
0x1002 0x5148 CHIP_R200 "ATI Radeon QH R200 8500"
|
0x1002 0x5148 CHIP_R200 "ATI Radeon QH R200 8500"
|
||||||
0x1002 0x514C CHIP_R200 "ATI Radeon QL R200 8500 LE"
|
0x1002 0x514C CHIP_R200 "ATI Radeon QL R200 8500 LE"
|
||||||
0x1002 0x514D CHIP_R200 "ATI Radeon QM R200 9100"
|
0x1002 0x514D CHIP_R200 "ATI Radeon QM R200 9100"
|
||||||
|
|
@ -76,59 +76,59 @@
|
||||||
0x1002 0x5159 CHIP_RV100 "ATI Radeon QY RV100 7000/VE"
|
0x1002 0x5159 CHIP_RV100 "ATI Radeon QY RV100 7000/VE"
|
||||||
0x1002 0x515A CHIP_RV100 "ATI Radeon QZ RV100 7000/VE"
|
0x1002 0x515A CHIP_RV100 "ATI Radeon QZ RV100 7000/VE"
|
||||||
0x1002 0x515E CHIP_RV100 "ATI ES1000 RN50"
|
0x1002 0x515E CHIP_RV100 "ATI ES1000 RN50"
|
||||||
0x1002 0x5460 CHIP_RV380|CHIP_IS_MOBILITY "ATI Radeon Mobility X300 M22"
|
0x1002 0x5460 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X300 M22"
|
||||||
0x1002 0x5462 CHIP_RV380|CHIP_IS_MOBILITY "ATI Radeon Mobility X600 SE M24C"
|
0x1002 0x5462 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 SE M24C"
|
||||||
0x1002 0x5464 CHIP_RV380|CHIP_IS_MOBILITY "ATI FireGL M22 GL 5464"
|
0x1002 0x5464 CHIP_RV380|RADEON_IS_MOBILITY "ATI FireGL M22 GL 5464"
|
||||||
0x1002 0x5548 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R423 X800"
|
0x1002 0x5548 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800"
|
||||||
0x1002 0x5549 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R423 X800 Pro"
|
0x1002 0x5549 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 Pro"
|
||||||
0x1002 0x554A CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R423 X800 XT PE"
|
0x1002 0x554A CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 XT PE"
|
||||||
0x1002 0x554B CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R423 X800 SE"
|
0x1002 0x554B CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 SE"
|
||||||
0x1002 0x554C CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R430 X800 XTP"
|
0x1002 0x554C CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R430 X800 XTP"
|
||||||
0x1002 0x554D CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R430 X800 XL"
|
0x1002 0x554D CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R430 X800 XL"
|
||||||
0x1002 0x554E CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R430 X800 SE"
|
0x1002 0x554E CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R430 X800 SE"
|
||||||
0x1002 0x554F CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R430 X800"
|
0x1002 0x554F CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R430 X800"
|
||||||
0x1002 0x5550 CHIP_R420|CHIP_NEW_MEMMAP "ATI FireGL V7100 R423"
|
0x1002 0x5550 CHIP_R420|RADEON_NEW_MEMMAP "ATI FireGL V7100 R423"
|
||||||
0x1002 0x5551 CHIP_R420|CHIP_NEW_MEMMAP "ATI FireGL V5100 R423 UQ"
|
0x1002 0x5551 CHIP_R420|RADEON_NEW_MEMMAP "ATI FireGL V5100 R423 UQ"
|
||||||
0x1002 0x5552 CHIP_R420|CHIP_NEW_MEMMAP "ATI FireGL unknown R423 UR"
|
0x1002 0x5552 CHIP_R420|RADEON_NEW_MEMMAP "ATI FireGL unknown R423 UR"
|
||||||
0x1002 0x5554 CHIP_R420|CHIP_NEW_MEMMAP "ATI FireGL unknown R423 UT"
|
0x1002 0x5554 CHIP_R420|RADEON_NEW_MEMMAP "ATI FireGL unknown R423 UT"
|
||||||
0x1002 0x564A CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Mobility FireGL V5000 M26"
|
0x1002 0x564A CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V5000 M26"
|
||||||
0x1002 0x564B CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Mobility FireGL V5000 M26"
|
0x1002 0x564B CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V5000 M26"
|
||||||
0x1002 0x564F CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon Mobility X700 XL M26"
|
0x1002 0x564F CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 XL M26"
|
||||||
0x1002 0x5652 CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
|
0x1002 0x5652 CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
|
||||||
0x1002 0x5653 CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
|
0x1002 0x5653 CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
|
||||||
0x1002 0x5834 CHIP_RS300|CHIP_IS_IGP "ATI Radeon RS300 9100 IGP"
|
0x1002 0x5834 CHIP_RS300|RADEON_IS_IGP "ATI Radeon RS300 9100 IGP"
|
||||||
0x1002 0x5835 CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY "ATI Radeon RS300 Mobility IGP"
|
0x1002 0x5835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS300 Mobility IGP"
|
||||||
0x1002 0x5960 CHIP_RV280 "ATI Radeon RV280 9250"
|
0x1002 0x5960 CHIP_RV280 "ATI Radeon RV280 9250"
|
||||||
0x1002 0x5961 CHIP_RV280 "ATI Radeon RV280 9200"
|
0x1002 0x5961 CHIP_RV280 "ATI Radeon RV280 9200"
|
||||||
0x1002 0x5962 CHIP_RV280 "ATI Radeon RV280 9200"
|
0x1002 0x5962 CHIP_RV280 "ATI Radeon RV280 9200"
|
||||||
0x1002 0x5964 CHIP_RV280 "ATI Radeon RV280 9200 SE"
|
0x1002 0x5964 CHIP_RV280 "ATI Radeon RV280 9200 SE"
|
||||||
0x1002 0x5965 CHIP_RV280 "ATI FireMV 2200 PCI"
|
0x1002 0x5965 CHIP_RV280 "ATI FireMV 2200 PCI"
|
||||||
0x1002 0x5969 CHIP_RV100 "ATI ES1000 RN50"
|
0x1002 0x5969 CHIP_RV100 "ATI ES1000 RN50"
|
||||||
0x1002 0x5b60 CHIP_RV380|CHIP_NEW_MEMMAP "ATI Radeon RV370 X300 SE"
|
0x1002 0x5b60 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X300 SE"
|
||||||
0x1002 0x5b62 CHIP_RV380|CHIP_NEW_MEMMAP "ATI Radeon RV370 X600 Pro"
|
0x1002 0x5b62 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X600 Pro"
|
||||||
0x1002 0x5b63 CHIP_RV380|CHIP_NEW_MEMMAP "ATI Radeon RV370 X550"
|
0x1002 0x5b63 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X550"
|
||||||
0x1002 0x5b64 CHIP_RV380|CHIP_NEW_MEMMAP "ATI FireGL V3100 (RV370) 5B64"
|
0x1002 0x5b64 CHIP_RV380|RADEON_NEW_MEMMAP "ATI FireGL V3100 (RV370) 5B64"
|
||||||
0x1002 0x5b65 CHIP_RV380|CHIP_NEW_MEMMAP "ATI FireMV 2200 PCIE (RV370) 5B65"
|
0x1002 0x5b65 CHIP_RV380|RADEON_NEW_MEMMAP "ATI FireMV 2200 PCIE (RV370) 5B65"
|
||||||
0x1002 0x5c61 CHIP_RV280|CHIP_IS_MOBILITY "ATI Radeon RV280 Mobility"
|
0x1002 0x5c61 CHIP_RV280|RADEON_IS_MOBILITY "ATI Radeon RV280 Mobility"
|
||||||
0x1002 0x5c63 CHIP_RV280|CHIP_IS_MOBILITY "ATI Radeon RV280 Mobility"
|
0x1002 0x5c63 CHIP_RV280|RADEON_IS_MOBILITY "ATI Radeon RV280 Mobility"
|
||||||
0x1002 0x5d48 CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Mobility Radeon X800 XT M28"
|
0x1002 0x5d48 CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X800 XT M28"
|
||||||
0x1002 0x5d49 CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Mobility FireGL V5100 M28"
|
0x1002 0x5d49 CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V5100 M28"
|
||||||
0x1002 0x5d4a CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Mobility Radeon X800 M28"
|
0x1002 0x5d4a CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X800 M28"
|
||||||
0x1002 0x5d4c CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R480 X850"
|
0x1002 0x5d4c CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R480 X850"
|
||||||
0x1002 0x5d4d CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R480 X850 XT PE"
|
0x1002 0x5d4d CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R480 X850 XT PE"
|
||||||
0x1002 0x5d4e CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R480 X850 SE"
|
0x1002 0x5d4e CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R480 X850 SE"
|
||||||
0x1002 0x5d4f CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R480 X850 Pro"
|
0x1002 0x5d4f CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R480 X850 Pro"
|
||||||
0x1002 0x5d50 CHIP_R420|CHIP_NEW_MEMMAP "ATI unknown Radeon / FireGL R480"
|
0x1002 0x5d50 CHIP_R420|RADEON_NEW_MEMMAP "ATI unknown Radeon / FireGL R480"
|
||||||
0x1002 0x5d52 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R480 X850 XT"
|
0x1002 0x5d52 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R480 X850 XT"
|
||||||
0x1002 0x5d57 CHIP_R420|CHIP_NEW_MEMMAP "ATI Radeon R423 X800 XT"
|
0x1002 0x5d57 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 XT"
|
||||||
0x1002 0x5e48 CHIP_RV410|CHIP_NEW_MEMMAP "ATI FireGL V5000 RV410"
|
0x1002 0x5e48 CHIP_RV410|RADEON_NEW_MEMMAP "ATI FireGL V5000 RV410"
|
||||||
0x1002 0x5e4a CHIP_RV410|CHIP_NEW_MEMMAP "ATI Radeon RV410 X700 XT"
|
0x1002 0x5e4a CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 XT"
|
||||||
0x1002 0x5e4b CHIP_RV410|CHIP_NEW_MEMMAP "ATI Radeon RV410 X700 Pro"
|
0x1002 0x5e4b CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 Pro"
|
||||||
0x1002 0x5e4c CHIP_RV410|CHIP_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
|
0x1002 0x5e4c CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
|
||||||
0x1002 0x5e4d CHIP_RV410|CHIP_NEW_MEMMAP "ATI Radeon RV410 X700"
|
0x1002 0x5e4d CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700"
|
||||||
0x1002 0x5e4f CHIP_RV410|CHIP_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
|
0x1002 0x5e4f CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
|
||||||
0x1002 0x7834 CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP "ATI Radeon RS350 9000/9100 IGP"
|
0x1002 0x7834 CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon RS350 9000/9100 IGP"
|
||||||
0x1002 0x7835 CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP "ATI Radeon RS350 Mobility IGP"
|
0x1002 0x7835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon RS350 Mobility IGP"
|
||||||
|
|
||||||
[r128]
|
[r128]
|
||||||
0x1002 0x4c45 0 "ATI Rage 128 Mobility LE (PCI)"
|
0x1002 0x4c45 0 "ATI Rage 128 Mobility LE (PCI)"
|
||||||
|
|
@ -186,6 +186,7 @@
|
||||||
0x1002 0x4c51 0 "3D Rage LT Pro"
|
0x1002 0x4c51 0 "3D Rage LT Pro"
|
||||||
0x1002 0x4c42 0 "3D Rage LT Pro AGP-133"
|
0x1002 0x4c42 0 "3D Rage LT Pro AGP-133"
|
||||||
0x1002 0x4c44 0 "3D Rage LT Pro AGP-66"
|
0x1002 0x4c44 0 "3D Rage LT Pro AGP-66"
|
||||||
|
0x1002 0x4759 0 "Rage 3D IICATI 3D RAGE IIC AGP(A12/A13)
|
||||||
0x1002 0x474c 0 "Rage XC"
|
0x1002 0x474c 0 "Rage XC"
|
||||||
0x1002 0x474f 0 "Rage XL"
|
0x1002 0x474f 0 "Rage XL"
|
||||||
0x1002 0x4752 0 "Rage XL"
|
0x1002 0x4752 0 "Rage XL"
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@
|
||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
|
|
||||||
#define IS_I965G(dev) (dev->pdev->device == 0x2972 || \
|
#define IS_I965G(dev) (dev->pci_device == 0x2972 || \
|
||||||
dev->pdev->device == 0x2982 || \
|
dev->pci_device == 0x2982 || \
|
||||||
dev->pdev->device == 0x2992 || \
|
dev->pci_device == 0x2992 || \
|
||||||
dev->pdev->device == 0x29A2)
|
dev->pci_device == 0x29A2)
|
||||||
|
|
||||||
|
|
||||||
/* Really want an OS-independent resettable timer. Would like to have
|
/* Really want an OS-independent resettable timer. Would like to have
|
||||||
|
|
@ -163,6 +163,7 @@ static int i915_initialize(drm_device_t * dev,
|
||||||
|
|
||||||
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
|
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
|
||||||
|
|
||||||
|
dev_priv->cpp = init->cpp;
|
||||||
dev_priv->back_offset = init->back_offset;
|
dev_priv->back_offset = init->back_offset;
|
||||||
dev_priv->front_offset = init->front_offset;
|
dev_priv->front_offset = init->front_offset;
|
||||||
dev_priv->current_page = 0;
|
dev_priv->current_page = 0;
|
||||||
|
|
@ -797,6 +798,7 @@ drm_ioctl_desc_t i915_ioctls[] = {
|
||||||
[DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
[DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||||
[DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
[DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||||
[DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
|
[DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
|
||||||
|
[DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH},
|
||||||
};
|
};
|
||||||
|
|
||||||
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,15 @@ typedef struct _drm_i915_sarea {
|
||||||
unsigned int depth_tiled;
|
unsigned int depth_tiled;
|
||||||
unsigned int rotated_tiled;
|
unsigned int rotated_tiled;
|
||||||
unsigned int rotated2_tiled;
|
unsigned int rotated2_tiled;
|
||||||
|
|
||||||
|
int pipeA_x;
|
||||||
|
int pipeA_y;
|
||||||
|
int pipeA_w;
|
||||||
|
int pipeA_h;
|
||||||
|
int pipeB_x;
|
||||||
|
int pipeB_y;
|
||||||
|
int pipeB_w;
|
||||||
|
int pipeB_h;
|
||||||
} drm_i915_sarea_t;
|
} drm_i915_sarea_t;
|
||||||
|
|
||||||
/* Flags for perf_boxes
|
/* Flags for perf_boxes
|
||||||
|
|
@ -132,6 +141,7 @@ typedef struct _drm_i915_sarea {
|
||||||
#define DRM_I915_DESTROY_HEAP 0x0c
|
#define DRM_I915_DESTROY_HEAP 0x0c
|
||||||
#define DRM_I915_SET_VBLANK_PIPE 0x0d
|
#define DRM_I915_SET_VBLANK_PIPE 0x0d
|
||||||
#define DRM_I915_GET_VBLANK_PIPE 0x0e
|
#define DRM_I915_GET_VBLANK_PIPE 0x0e
|
||||||
|
#define DRM_I915_VBLANK_SWAP 0x0f
|
||||||
|
|
||||||
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
||||||
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
||||||
|
|
@ -148,6 +158,7 @@ typedef struct _drm_i915_sarea {
|
||||||
#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
|
#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
|
||||||
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
|
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
|
||||||
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
|
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
|
||||||
|
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
|
||||||
|
|
||||||
|
|
||||||
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
||||||
|
|
@ -244,4 +255,12 @@ typedef struct drm_i915_vblank_pipe {
|
||||||
int pipe;
|
int pipe;
|
||||||
} drm_i915_vblank_pipe_t;
|
} drm_i915_vblank_pipe_t;
|
||||||
|
|
||||||
|
/* Schedule buffer swap at given vertical blank:
|
||||||
|
*/
|
||||||
|
typedef struct drm_i915_vblank_swap {
|
||||||
|
drm_drawable_t drawable;
|
||||||
|
drm_vblank_seq_type_t seqtype;
|
||||||
|
unsigned int sequence;
|
||||||
|
} drm_i915_vblank_swap_t;
|
||||||
|
|
||||||
#endif /* _I915_DRM_H_ */
|
#endif /* _I915_DRM_H_ */
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,11 @@
|
||||||
* 1.3: Add vblank support
|
* 1.3: Add vblank support
|
||||||
* 1.4: Fix cmdbuffer path, add heap destroy
|
* 1.4: Fix cmdbuffer path, add heap destroy
|
||||||
* 1.5: Add vblank pipe configuration
|
* 1.5: Add vblank pipe configuration
|
||||||
|
* 1.6: - New ioctl for scheduling buffer swaps on vertical blank
|
||||||
|
* - Support vertical blank on secondary display pipe
|
||||||
*/
|
*/
|
||||||
#define DRIVER_MAJOR 1
|
#define DRIVER_MAJOR 1
|
||||||
#define DRIVER_MINOR 5
|
#define DRIVER_MINOR 6
|
||||||
#define DRIVER_PATCHLEVEL 0
|
#define DRIVER_PATCHLEVEL 0
|
||||||
|
|
||||||
typedef struct _drm_i915_ring_buffer {
|
typedef struct _drm_i915_ring_buffer {
|
||||||
|
|
@ -71,6 +73,13 @@ struct mem_block {
|
||||||
DRMFILE filp; /* 0: free, -1: heap, other: real files */
|
DRMFILE filp; /* 0: free, -1: heap, other: real files */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _drm_i915_vbl_swap {
|
||||||
|
struct list_head head;
|
||||||
|
drm_drawable_t drw_id;
|
||||||
|
unsigned int pipe;
|
||||||
|
unsigned int sequence;
|
||||||
|
} drm_i915_vbl_swap_t;
|
||||||
|
|
||||||
typedef struct drm_i915_private {
|
typedef struct drm_i915_private {
|
||||||
drm_local_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_local_map_t *mmio_map;
|
drm_local_map_t *mmio_map;
|
||||||
|
|
@ -83,6 +92,7 @@ typedef struct drm_i915_private {
|
||||||
dma_addr_t dma_status_page;
|
dma_addr_t dma_status_page;
|
||||||
unsigned long counter;
|
unsigned long counter;
|
||||||
|
|
||||||
|
unsigned int cpp;
|
||||||
int back_offset;
|
int back_offset;
|
||||||
int front_offset;
|
int front_offset;
|
||||||
int current_page;
|
int current_page;
|
||||||
|
|
@ -98,6 +108,10 @@ typedef struct drm_i915_private {
|
||||||
struct mem_block *agp_heap;
|
struct mem_block *agp_heap;
|
||||||
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
||||||
int vblank_pipe;
|
int vblank_pipe;
|
||||||
|
|
||||||
|
spinlock_t swaps_lock;
|
||||||
|
drm_i915_vbl_swap_t vbl_swaps;
|
||||||
|
unsigned int swaps_pending;
|
||||||
} drm_i915_private_t;
|
} drm_i915_private_t;
|
||||||
|
|
||||||
extern drm_ioctl_desc_t i915_ioctls[];
|
extern drm_ioctl_desc_t i915_ioctls[];
|
||||||
|
|
@ -117,12 +131,14 @@ extern int i915_irq_emit(DRM_IOCTL_ARGS);
|
||||||
extern int i915_irq_wait(DRM_IOCTL_ARGS);
|
extern int i915_irq_wait(DRM_IOCTL_ARGS);
|
||||||
|
|
||||||
extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
|
extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
|
||||||
|
extern int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence);
|
||||||
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
|
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
|
||||||
extern void i915_driver_irq_preinstall(drm_device_t * dev);
|
extern void i915_driver_irq_preinstall(drm_device_t * dev);
|
||||||
extern void i915_driver_irq_postinstall(drm_device_t * dev);
|
extern void i915_driver_irq_postinstall(drm_device_t * dev);
|
||||||
extern void i915_driver_irq_uninstall(drm_device_t * dev);
|
extern void i915_driver_irq_uninstall(drm_device_t * dev);
|
||||||
extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
|
extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
|
||||||
extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
|
extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
|
||||||
|
extern int i915_vblank_swap(DRM_IOCTL_ARGS);
|
||||||
|
|
||||||
/* i915_mem.c */
|
/* i915_mem.c */
|
||||||
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
|
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
|
||||||
|
|
@ -256,6 +272,10 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
|
||||||
|
|
||||||
#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
|
#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
|
||||||
|
|
||||||
|
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
|
||||||
|
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
|
||||||
|
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
|
||||||
|
|
||||||
#define MI_BATCH_BUFFER ((0x30<<23)|1)
|
#define MI_BATCH_BUFFER ((0x30<<23)|1)
|
||||||
#define MI_BATCH_BUFFER_START (0x31<<23)
|
#define MI_BATCH_BUFFER_START (0x31<<23)
|
||||||
#define MI_BATCH_BUFFER_END (0xA<<23)
|
#define MI_BATCH_BUFFER_END (0xA<<23)
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,99 @@
|
||||||
|
|
||||||
#define MAX_NOPID ((u32)~0)
|
#define MAX_NOPID ((u32)~0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit blits for scheduled buffer swaps.
|
||||||
|
*
|
||||||
|
* This function will be called with the HW lock held.
|
||||||
|
*/
|
||||||
|
static void i915_vblank_tasklet(drm_device_t *dev)
|
||||||
|
{
|
||||||
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
|
unsigned long irqflags;
|
||||||
|
struct list_head *list, *tmp;
|
||||||
|
|
||||||
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||||
|
|
||||||
|
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
|
||||||
|
drm_i915_vbl_swap_t *vbl_swap =
|
||||||
|
list_entry(list, drm_i915_vbl_swap_t, head);
|
||||||
|
atomic_t *counter = vbl_swap->pipe ? &dev->vbl_received2 :
|
||||||
|
&dev->vbl_received;
|
||||||
|
|
||||||
|
if ((atomic_read(counter) - vbl_swap->sequence) <= (1<<23)) {
|
||||||
|
drm_drawable_info_t *drw;
|
||||||
|
|
||||||
|
spin_unlock(&dev_priv->swaps_lock);
|
||||||
|
|
||||||
|
spin_lock(&dev->drw_lock);
|
||||||
|
|
||||||
|
drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
|
||||||
|
|
||||||
|
if (drw) {
|
||||||
|
int i, num_rects = drw->num_rects;
|
||||||
|
drm_clip_rect_t *rect = drw->rects;
|
||||||
|
drm_i915_sarea_t *sarea_priv =
|
||||||
|
dev_priv->sarea_priv;
|
||||||
|
u32 cpp = dev_priv->cpp;
|
||||||
|
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
|
||||||
|
XY_SRC_COPY_BLT_WRITE_ALPHA |
|
||||||
|
XY_SRC_COPY_BLT_WRITE_RGB)
|
||||||
|
: XY_SRC_COPY_BLT_CMD;
|
||||||
|
u32 pitchropcpp = (sarea_priv->pitch * cpp) |
|
||||||
|
(0xcc << 16) | (cpp << 23) |
|
||||||
|
(1 << 24);
|
||||||
|
RING_LOCALS;
|
||||||
|
|
||||||
|
i915_kernel_lost_context(dev);
|
||||||
|
|
||||||
|
BEGIN_LP_RING(6);
|
||||||
|
|
||||||
|
OUT_RING(GFX_OP_DRAWRECT_INFO);
|
||||||
|
OUT_RING(0);
|
||||||
|
OUT_RING(0);
|
||||||
|
OUT_RING(sarea_priv->width |
|
||||||
|
sarea_priv->height << 16);
|
||||||
|
OUT_RING(sarea_priv->width |
|
||||||
|
sarea_priv->height << 16);
|
||||||
|
OUT_RING(0);
|
||||||
|
|
||||||
|
ADVANCE_LP_RING();
|
||||||
|
|
||||||
|
sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rects; i++, rect++) {
|
||||||
|
BEGIN_LP_RING(8);
|
||||||
|
|
||||||
|
OUT_RING(cmd);
|
||||||
|
OUT_RING(pitchropcpp);
|
||||||
|
OUT_RING((rect->y1 << 16) | rect->x1);
|
||||||
|
OUT_RING((rect->y2 << 16) | rect->x2);
|
||||||
|
OUT_RING(sarea_priv->front_offset);
|
||||||
|
OUT_RING((rect->y1 << 16) | rect->x1);
|
||||||
|
OUT_RING(pitchropcpp & 0xffff);
|
||||||
|
OUT_RING(sarea_priv->back_offset);
|
||||||
|
|
||||||
|
ADVANCE_LP_RING();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock(&dev->drw_lock);
|
||||||
|
|
||||||
|
spin_lock(&dev_priv->swaps_lock);
|
||||||
|
|
||||||
|
list_del(list);
|
||||||
|
|
||||||
|
drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
|
||||||
|
|
||||||
|
dev_priv->swaps_pending--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||||
|
}
|
||||||
|
|
||||||
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||||
{
|
{
|
||||||
drm_device_t *dev = (drm_device_t *) arg;
|
drm_device_t *dev = (drm_device_t *) arg;
|
||||||
|
|
@ -60,9 +153,26 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||||
DRM_WAKEUP(&dev_priv->irq_queue);
|
DRM_WAKEUP(&dev_priv->irq_queue);
|
||||||
|
|
||||||
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
|
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
|
||||||
atomic_inc(&dev->vbl_received);
|
int vblank_pipe = dev_priv->vblank_pipe;
|
||||||
|
|
||||||
|
if ((vblank_pipe &
|
||||||
|
(DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
|
||||||
|
== (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
|
||||||
|
if (temp & VSYNC_PIPEA_FLAG)
|
||||||
|
atomic_inc(&dev->vbl_received);
|
||||||
|
if (temp & VSYNC_PIPEB_FLAG)
|
||||||
|
atomic_inc(&dev->vbl_received2);
|
||||||
|
} else if (((temp & VSYNC_PIPEA_FLAG) &&
|
||||||
|
(vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
|
||||||
|
((temp & VSYNC_PIPEB_FLAG) &&
|
||||||
|
(vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
|
||||||
|
atomic_inc(&dev->vbl_received);
|
||||||
|
|
||||||
DRM_WAKEUP(&dev->vbl_queue);
|
DRM_WAKEUP(&dev->vbl_queue);
|
||||||
drm_vbl_send_signals(dev);
|
drm_vbl_send_signals(dev);
|
||||||
|
|
||||||
|
if (dev_priv->swaps_pending > 0)
|
||||||
|
drm_locked_tasklet(dev, i915_vblank_tasklet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
@ -124,7 +234,8 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence,
|
||||||
|
atomic_t *counter)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
unsigned int cur_vblank;
|
unsigned int cur_vblank;
|
||||||
|
|
@ -136,7 +247,7 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
||||||
(((cur_vblank = atomic_read(&dev->vbl_received))
|
(((cur_vblank = atomic_read(counter))
|
||||||
- *sequence) <= (1<<23)));
|
- *sequence) <= (1<<23)));
|
||||||
|
|
||||||
*sequence = cur_vblank;
|
*sequence = cur_vblank;
|
||||||
|
|
@ -144,6 +255,16 @@ int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||||
|
{
|
||||||
|
return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence)
|
||||||
|
{
|
||||||
|
return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Needs the lock as it touches the ring.
|
/* Needs the lock as it touches the ring.
|
||||||
*/
|
*/
|
||||||
int i915_irq_emit(DRM_IOCTL_ARGS)
|
int i915_irq_emit(DRM_IOCTL_ARGS)
|
||||||
|
|
@ -192,7 +313,7 @@ int i915_irq_wait(DRM_IOCTL_ARGS)
|
||||||
return i915_wait_irq(dev, irqwait.irq_seq);
|
return i915_wait_irq(dev, irqwait.irq_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int i915_enable_interrupt (drm_device_t *dev)
|
static void i915_enable_interrupt (drm_device_t *dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
u16 flag;
|
u16 flag;
|
||||||
|
|
@ -202,13 +323,8 @@ static int i915_enable_interrupt (drm_device_t *dev)
|
||||||
flag |= VSYNC_PIPEA_FLAG;
|
flag |= VSYNC_PIPEA_FLAG;
|
||||||
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
|
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
|
||||||
flag |= VSYNC_PIPEB_FLAG;
|
flag |= VSYNC_PIPEB_FLAG;
|
||||||
if (dev_priv->vblank_pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
|
|
||||||
DRM_ERROR("%s called with invalid pipe 0x%x\n",
|
|
||||||
__FUNCTION__, dev_priv->vblank_pipe);
|
|
||||||
return DRM_ERR(EINVAL);
|
|
||||||
}
|
|
||||||
I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
|
I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the vblank monitor pipe
|
/* Set the vblank monitor pipe
|
||||||
|
|
@ -227,8 +343,17 @@ int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
|
||||||
DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
|
DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
|
||||||
sizeof(pipe));
|
sizeof(pipe));
|
||||||
|
|
||||||
|
if (pipe.pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
|
||||||
|
DRM_ERROR("%s called with invalid pipe 0x%x\n",
|
||||||
|
__FUNCTION__, pipe.pipe);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
dev_priv->vblank_pipe = pipe.pipe;
|
dev_priv->vblank_pipe = pipe.pipe;
|
||||||
return i915_enable_interrupt (dev);
|
|
||||||
|
i915_enable_interrupt (dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
|
int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
|
||||||
|
|
@ -254,6 +379,118 @@ int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule buffer swap at given vertical blank.
|
||||||
|
*/
|
||||||
|
int i915_vblank_swap(DRM_IOCTL_ARGS)
|
||||||
|
{
|
||||||
|
DRM_DEVICE;
|
||||||
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
|
drm_i915_vblank_swap_t swap;
|
||||||
|
drm_i915_vbl_swap_t *vbl_swap;
|
||||||
|
unsigned int pipe, seqtype, curseq;
|
||||||
|
unsigned long irqflags;
|
||||||
|
struct list_head *list;
|
||||||
|
|
||||||
|
if (!dev_priv) {
|
||||||
|
DRM_ERROR("%s called with no initialization\n", __func__);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_priv->sarea_priv->rotation) {
|
||||||
|
DRM_DEBUG("Rotation not supported\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_COPY_FROM_USER_IOCTL(swap, (drm_i915_vblank_swap_t __user *) data,
|
||||||
|
sizeof(swap));
|
||||||
|
|
||||||
|
if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
|
||||||
|
_DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) {
|
||||||
|
DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe = (swap.seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
|
||||||
|
|
||||||
|
seqtype = swap.seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
|
||||||
|
|
||||||
|
if (!(dev_priv->vblank_pipe & (1 << pipe))) {
|
||||||
|
DRM_ERROR("Invalid pipe %d\n", pipe);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
if (!drm_get_drawable_info(dev, swap.drawable)) {
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
DRM_ERROR("Invalid drawable ID %d\n", swap.drawable);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
|
||||||
|
|
||||||
|
curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
|
||||||
|
|
||||||
|
if (seqtype == _DRM_VBLANK_RELATIVE)
|
||||||
|
swap.sequence += curseq;
|
||||||
|
|
||||||
|
if ((curseq - swap.sequence) <= (1<<23)) {
|
||||||
|
if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) {
|
||||||
|
swap.sequence = curseq + 1;
|
||||||
|
} else {
|
||||||
|
DRM_DEBUG("Missed target sequence\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||||
|
|
||||||
|
list_for_each(list, &dev_priv->vbl_swaps.head) {
|
||||||
|
vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
|
||||||
|
|
||||||
|
if (vbl_swap->drw_id == swap.drawable &&
|
||||||
|
vbl_swap->pipe == pipe &&
|
||||||
|
vbl_swap->sequence == swap.sequence) {
|
||||||
|
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||||
|
DRM_DEBUG("Already scheduled\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||||
|
|
||||||
|
if (dev_priv->swaps_pending >= 100) {
|
||||||
|
DRM_DEBUG("Too many swaps queued\n");
|
||||||
|
return DRM_ERR(EBUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
vbl_swap = drm_calloc(1, sizeof(vbl_swap), DRM_MEM_DRIVER);
|
||||||
|
|
||||||
|
if (!vbl_swap) {
|
||||||
|
DRM_ERROR("Failed to allocate memory to queue swap\n");
|
||||||
|
return DRM_ERR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
vbl_swap->drw_id = swap.drawable;
|
||||||
|
vbl_swap->pipe = pipe;
|
||||||
|
vbl_swap->sequence = swap.sequence;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
|
||||||
|
|
||||||
|
list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
|
||||||
|
dev_priv->swaps_pending++;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
|
||||||
|
|
||||||
|
DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_swap_t __user *) data, swap,
|
||||||
|
sizeof(swap));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* drm_dma.h hooks
|
/* drm_dma.h hooks
|
||||||
*/
|
*/
|
||||||
void i915_driver_irq_preinstall(drm_device_t * dev)
|
void i915_driver_irq_preinstall(drm_device_t * dev)
|
||||||
|
|
@ -269,6 +506,12 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
|
||||||
{
|
{
|
||||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||||
|
|
||||||
|
dev_priv->swaps_lock = SPIN_LOCK_UNLOCKED;
|
||||||
|
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
|
||||||
|
dev_priv->swaps_pending = 0;
|
||||||
|
|
||||||
|
if (!dev_priv->vblank_pipe)
|
||||||
|
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
|
||||||
i915_enable_interrupt(dev);
|
i915_enable_interrupt(dev);
|
||||||
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
|
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -815,17 +815,18 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init)
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset);
|
||||||
|
if (!dev_priv->ring_map) {
|
||||||
|
DRM_ERROR("can not find ring map!\n");
|
||||||
|
dev->dev_private = (void *)dev_priv;
|
||||||
|
mach64_do_cleanup_dma(dev);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
dev_priv->sarea_priv = (drm_mach64_sarea_t *)
|
dev_priv->sarea_priv = (drm_mach64_sarea_t *)
|
||||||
((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
|
((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
|
||||||
|
|
||||||
if (!dev_priv->is_pci) {
|
if (!dev_priv->is_pci) {
|
||||||
dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset);
|
|
||||||
if (!dev_priv->ring_map) {
|
|
||||||
DRM_ERROR("can not find ring map!\n");
|
|
||||||
dev->dev_private = (void *)dev_priv;
|
|
||||||
mach64_do_cleanup_dma(dev);
|
|
||||||
return DRM_ERR(EINVAL);
|
|
||||||
}
|
|
||||||
drm_core_ioremap(dev_priv->ring_map, dev);
|
drm_core_ioremap(dev_priv->ring_map, dev);
|
||||||
if (!dev_priv->ring_map->handle) {
|
if (!dev_priv->ring_map->handle) {
|
||||||
DRM_ERROR("can not ioremap virtual address for"
|
DRM_ERROR("can not ioremap virtual address for"
|
||||||
|
|
@ -834,6 +835,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init)
|
||||||
mach64_do_cleanup_dma(dev);
|
mach64_do_cleanup_dma(dev);
|
||||||
return DRM_ERR(ENOMEM);
|
return DRM_ERR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
dev->agp_buffer_token = init->buffers_offset;
|
||||||
dev->agp_buffer_map =
|
dev->agp_buffer_map =
|
||||||
drm_core_findmap(dev, init->buffers_offset);
|
drm_core_findmap(dev, init->buffers_offset);
|
||||||
if (!dev->agp_buffer_map) {
|
if (!dev->agp_buffer_map) {
|
||||||
|
|
@ -890,27 +892,9 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate descriptor memory from pci pool */
|
|
||||||
DRM_DEBUG("Allocating dma descriptor ring\n");
|
|
||||||
dev_priv->ring.size = 0x4000; /* 16KB */
|
dev_priv->ring.size = 0x4000; /* 16KB */
|
||||||
|
dev_priv->ring.start = dev_priv->ring_map->handle;
|
||||||
if (dev_priv->is_pci) {
|
dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset;
|
||||||
dev_priv->ring.dmah = drm_pci_alloc(dev, dev_priv->ring.size,
|
|
||||||
dev_priv->ring.size,
|
|
||||||
0xfffffffful);
|
|
||||||
|
|
||||||
if (!dev_priv->ring.dmah) {
|
|
||||||
DRM_ERROR("Allocating dma descriptor ring failed\n");
|
|
||||||
return DRM_ERR(ENOMEM);
|
|
||||||
} else {
|
|
||||||
dev_priv->ring.start = dev_priv->ring.dmah->vaddr;
|
|
||||||
dev_priv->ring.start_addr =
|
|
||||||
(u32) dev_priv->ring.dmah->busaddr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dev_priv->ring.start = dev_priv->ring_map->handle;
|
|
||||||
dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(dev_priv->ring.start, 0, dev_priv->ring.size);
|
memset(dev_priv->ring.start, 0, dev_priv->ring.size);
|
||||||
DRM_INFO("descriptor ring: cpu addr %p, bus addr: 0x%08x\n",
|
DRM_INFO("descriptor ring: cpu addr %p, bus addr: 0x%08x\n",
|
||||||
|
|
@ -1148,18 +1132,14 @@ int mach64_do_cleanup_dma(drm_device_t * dev)
|
||||||
if (dev->dev_private) {
|
if (dev->dev_private) {
|
||||||
drm_mach64_private_t *dev_priv = dev->dev_private;
|
drm_mach64_private_t *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
if (dev_priv->is_pci) {
|
if (!dev_priv->is_pci) {
|
||||||
if (dev_priv->ring.dmah) {
|
|
||||||
drm_pci_free(dev, dev_priv->ring.dmah);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dev_priv->ring_map)
|
if (dev_priv->ring_map)
|
||||||
drm_core_ioremapfree(dev_priv->ring_map, dev);
|
drm_core_ioremapfree(dev_priv->ring_map, dev);
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->agp_buffer_map) {
|
if (dev->agp_buffer_map) {
|
||||||
drm_core_ioremapfree(dev->agp_buffer_map, dev);
|
drm_core_ioremapfree(dev->agp_buffer_map, dev);
|
||||||
dev->agp_buffer_map = NULL;
|
dev->agp_buffer_map = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mach64_destroy_freelist(dev);
|
mach64_destroy_freelist(dev);
|
||||||
|
|
@ -1328,17 +1308,88 @@ int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
|
||||||
|
{
|
||||||
|
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
|
||||||
|
struct list_head *ptr;
|
||||||
|
struct list_head *tmp;
|
||||||
|
drm_mach64_freelist_t *entry;
|
||||||
|
u32 head, tail, ofs;
|
||||||
|
|
||||||
|
mach64_ring_tick(dev_priv, ring);
|
||||||
|
head = ring->head;
|
||||||
|
tail = ring->tail;
|
||||||
|
|
||||||
|
if (head == tail) {
|
||||||
|
#if MACH64_EXTRA_CHECKING
|
||||||
|
if (MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE) {
|
||||||
|
DRM_ERROR("Empty ring with non-idle engine!\n");
|
||||||
|
mach64_dump_ring_info(dev_priv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* last pass is complete, so release everything */
|
||||||
|
mach64_do_release_used_buffers(dev_priv);
|
||||||
|
DRM_DEBUG("%s: idle engine, freed all buffers.\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
if (list_empty(&dev_priv->free_list)) {
|
||||||
|
DRM_ERROR("Freelist empty with idle engine\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Look for a completed buffer and bail out of the loop
|
||||||
|
* as soon as we find one -- don't waste time trying
|
||||||
|
* to free extra bufs here, leave that to do_release_used_buffers
|
||||||
|
*/
|
||||||
|
list_for_each_safe(ptr, tmp, &dev_priv->pending) {
|
||||||
|
entry = list_entry(ptr, drm_mach64_freelist_t, list);
|
||||||
|
ofs = entry->ring_ofs;
|
||||||
|
if (entry->discard &&
|
||||||
|
((head < tail && (ofs < head || ofs >= tail)) ||
|
||||||
|
(head > tail && (ofs < head && ofs >= tail)))) {
|
||||||
|
#if MACH64_EXTRA_CHECKING
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = head; i != tail; i = (i + 4) & ring->tail_mask)
|
||||||
|
{
|
||||||
|
u32 o1 = le32_to_cpu(((u32 *) ring->
|
||||||
|
start)[i + 1]);
|
||||||
|
u32 o2 = GETBUFADDR(entry->buf);
|
||||||
|
|
||||||
|
if (o1 == o2) {
|
||||||
|
DRM_ERROR
|
||||||
|
("Attempting to free used buffer: "
|
||||||
|
"i=%d buf=0x%08x\n",
|
||||||
|
i, o1);
|
||||||
|
mach64_dump_ring_info(dev_priv);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* found a processed buffer */
|
||||||
|
entry->buf->pending = 0;
|
||||||
|
list_del(ptr);
|
||||||
|
list_add_tail(ptr, &dev_priv->free_list);
|
||||||
|
DRM_DEBUG
|
||||||
|
("%s: freed processed buffer (head=%d tail=%d "
|
||||||
|
"buf ring ofs=%d).\n",
|
||||||
|
__FUNCTION__, head, tail, ofs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv)
|
drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv)
|
||||||
{
|
{
|
||||||
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
|
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
|
||||||
drm_mach64_freelist_t *entry;
|
drm_mach64_freelist_t *entry;
|
||||||
struct list_head *ptr;
|
struct list_head *ptr;
|
||||||
struct list_head *tmp;
|
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
if (list_empty(&dev_priv->free_list)) {
|
if (list_empty(&dev_priv->free_list)) {
|
||||||
u32 head, tail, ofs;
|
|
||||||
|
|
||||||
if (list_empty(&dev_priv->pending)) {
|
if (list_empty(&dev_priv->pending)) {
|
||||||
DRM_ERROR
|
DRM_ERROR
|
||||||
("Couldn't get buffer - pending and free lists empty\n");
|
("Couldn't get buffer - pending and free lists empty\n");
|
||||||
|
|
@ -1350,81 +1401,15 @@ drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tail = ring->tail;
|
|
||||||
for (t = 0; t < dev_priv->usec_timeout; t++) {
|
for (t = 0; t < dev_priv->usec_timeout; t++) {
|
||||||
mach64_ring_tick(dev_priv, ring);
|
int ret;
|
||||||
head = ring->head;
|
|
||||||
|
|
||||||
if (head == tail) {
|
ret = mach64_do_reclaim_completed(dev_priv);
|
||||||
#if MACH64_EXTRA_CHECKING
|
if (ret == 0)
|
||||||
if (MACH64_READ(MACH64_GUI_STAT) &
|
|
||||||
MACH64_GUI_ACTIVE) {
|
|
||||||
DRM_ERROR
|
|
||||||
("Empty ring with non-idle engine!\n");
|
|
||||||
mach64_dump_ring_info(dev_priv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* last pass is complete, so release everything */
|
|
||||||
mach64_do_release_used_buffers(dev_priv);
|
|
||||||
DRM_DEBUG
|
|
||||||
("%s: idle engine, freed all buffers.\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
if (list_empty(&dev_priv->free_list)) {
|
|
||||||
DRM_ERROR
|
|
||||||
("Freelist empty with idle engine\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
goto _freelist_entry_found;
|
goto _freelist_entry_found;
|
||||||
}
|
if (ret < 0)
|
||||||
/* Look for a completed buffer and bail out of the loop
|
return NULL;
|
||||||
* as soon as we find one -- don't waste time trying
|
|
||||||
* to free extra bufs here, leave that to do_release_used_buffers
|
|
||||||
*/
|
|
||||||
list_for_each_safe(ptr, tmp, &dev_priv->pending) {
|
|
||||||
entry =
|
|
||||||
list_entry(ptr, drm_mach64_freelist_t,
|
|
||||||
list);
|
|
||||||
ofs = entry->ring_ofs;
|
|
||||||
if (entry->discard &&
|
|
||||||
((head < tail
|
|
||||||
&& (ofs < head || ofs >= tail))
|
|
||||||
|| (head > tail
|
|
||||||
&& (ofs < head && ofs >= tail)))) {
|
|
||||||
#if MACH64_EXTRA_CHECKING
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = head; i != tail;
|
|
||||||
i = (i + 4) & ring->tail_mask) {
|
|
||||||
u32 o1 =
|
|
||||||
le32_to_cpu(((u32 *) ring->
|
|
||||||
start)[i + 1]);
|
|
||||||
u32 o2 = GETBUFADDR(entry->buf);
|
|
||||||
|
|
||||||
if (o1 == o2) {
|
|
||||||
DRM_ERROR
|
|
||||||
("Attempting to free used buffer: "
|
|
||||||
"i=%d buf=0x%08x\n",
|
|
||||||
i, o1);
|
|
||||||
mach64_dump_ring_info
|
|
||||||
(dev_priv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* found a processed buffer */
|
|
||||||
entry->buf->pending = 0;
|
|
||||||
list_del(ptr);
|
|
||||||
entry->buf->used = 0;
|
|
||||||
list_add_tail(ptr,
|
|
||||||
&dev_priv->placeholders);
|
|
||||||
DRM_DEBUG
|
|
||||||
("%s: freed processed buffer (head=%d tail=%d "
|
|
||||||
"buf ring ofs=%d).\n",
|
|
||||||
__FUNCTION__, head, tail, ofs);
|
|
||||||
return entry->buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DRM_UDELAY(1);
|
DRM_UDELAY(1);
|
||||||
}
|
}
|
||||||
mach64_dump_ring_info(dev_priv);
|
mach64_dump_ring_info(dev_priv);
|
||||||
|
|
@ -1443,6 +1428,33 @@ drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv)
|
||||||
return entry->buf;
|
return entry->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mach64_freelist_put(drm_mach64_private_t * dev_priv, drm_buf_t * copy_buf)
|
||||||
|
{
|
||||||
|
struct list_head *ptr;
|
||||||
|
drm_mach64_freelist_t *entry;
|
||||||
|
|
||||||
|
#if MACH64_EXTRA_CHECKING
|
||||||
|
list_for_each(ptr, &dev_priv->pending) {
|
||||||
|
entry = list_entry(ptr, drm_mach64_freelist_t, list);
|
||||||
|
if (copy_buf == entry->buf) {
|
||||||
|
DRM_ERROR("%s: Trying to release a pending buf\n",
|
||||||
|
__FUNCTION__);
|
||||||
|
return DRM_ERR(EFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ptr = dev_priv->placeholders.next;
|
||||||
|
entry = list_entry(ptr, drm_mach64_freelist_t, list);
|
||||||
|
copy_buf->pending = 0;
|
||||||
|
copy_buf->used = 0;
|
||||||
|
entry->buf = copy_buf;
|
||||||
|
entry->discard = 1;
|
||||||
|
list_del(ptr);
|
||||||
|
list_add_tail(ptr, &dev_priv->free_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ typedef struct drm_mach64_vertex {
|
||||||
} drm_mach64_vertex_t;
|
} drm_mach64_vertex_t;
|
||||||
|
|
||||||
typedef struct drm_mach64_blit {
|
typedef struct drm_mach64_blit {
|
||||||
int idx;
|
void *buf;
|
||||||
int pitch;
|
int pitch;
|
||||||
int offset;
|
int offset;
|
||||||
int format;
|
int format;
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@
|
||||||
|
|
||||||
#define DRIVER_NAME "mach64"
|
#define DRIVER_NAME "mach64"
|
||||||
#define DRIVER_DESC "DRM module for the ATI Rage Pro"
|
#define DRIVER_DESC "DRM module for the ATI Rage Pro"
|
||||||
#define DRIVER_DATE "20020904"
|
#define DRIVER_DATE "20060718"
|
||||||
|
|
||||||
#define DRIVER_MAJOR 1
|
#define DRIVER_MAJOR 2
|
||||||
#define DRIVER_MINOR 0
|
#define DRIVER_MINOR 0
|
||||||
#define DRIVER_PATCHLEVEL 0
|
#define DRIVER_PATCHLEVEL 0
|
||||||
|
|
||||||
|
|
@ -61,7 +61,6 @@ typedef struct drm_mach64_freelist {
|
||||||
} drm_mach64_freelist_t;
|
} drm_mach64_freelist_t;
|
||||||
|
|
||||||
typedef struct drm_mach64_descriptor_ring {
|
typedef struct drm_mach64_descriptor_ring {
|
||||||
drm_dma_handle_t *dmah; /* Handle to pci dma memory */
|
|
||||||
void *start; /* write pointer (cpu address) to start of descriptor ring */
|
void *start; /* write pointer (cpu address) to start of descriptor ring */
|
||||||
u32 start_addr; /* bus address of beginning of descriptor ring */
|
u32 start_addr; /* bus address of beginning of descriptor ring */
|
||||||
int size; /* size of ring in bytes */
|
int size; /* size of ring in bytes */
|
||||||
|
|
@ -123,6 +122,8 @@ extern void mach64_driver_lastclose(drm_device_t * dev);
|
||||||
extern int mach64_init_freelist(drm_device_t * dev);
|
extern int mach64_init_freelist(drm_device_t * dev);
|
||||||
extern void mach64_destroy_freelist(drm_device_t * dev);
|
extern void mach64_destroy_freelist(drm_device_t * dev);
|
||||||
extern drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv);
|
extern drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv);
|
||||||
|
extern int mach64_freelist_put(drm_mach64_private_t * dev_priv,
|
||||||
|
drm_buf_t * copy_buf);
|
||||||
|
|
||||||
extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,
|
extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,
|
||||||
int entries);
|
int entries);
|
||||||
|
|
|
||||||
|
|
@ -480,16 +480,16 @@ static int mach64_do_get_frames_queued(drm_mach64_private_t * dev_priv)
|
||||||
/* Copy and verify a client submited buffer.
|
/* Copy and verify a client submited buffer.
|
||||||
* FIXME: Make an assembly optimized version
|
* FIXME: Make an assembly optimized version
|
||||||
*/
|
*/
|
||||||
static __inline__ int copy_and_verify_from_user(u32 *to,
|
static __inline__ int copy_from_user_vertex(u32 *to,
|
||||||
const u32 __user *ufrom,
|
const u32 __user *ufrom,
|
||||||
unsigned long bytes)
|
unsigned long bytes)
|
||||||
{
|
{
|
||||||
unsigned long n = bytes; /* dwords remaining in buffer */
|
unsigned long n = bytes; /* dwords remaining in buffer */
|
||||||
u32 *from, *orig_from;
|
u32 *from, *orig_from;
|
||||||
|
|
||||||
from = drm_alloc(bytes, DRM_MEM_DRIVER);
|
from = drm_alloc(bytes, DRM_MEM_DRIVER);
|
||||||
if (from == NULL)
|
if (from == NULL)
|
||||||
return ENOMEM;
|
return DRM_ERR(ENOMEM);
|
||||||
|
|
||||||
if (DRM_COPY_FROM_USER(from, ufrom, bytes)) {
|
if (DRM_COPY_FROM_USER(from, ufrom, bytes)) {
|
||||||
drm_free(from, bytes, DRM_MEM_DRIVER);
|
drm_free(from, bytes, DRM_MEM_DRIVER);
|
||||||
|
|
@ -546,12 +546,15 @@ static __inline__ int copy_and_verify_from_user(u32 *to,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev,
|
static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev,
|
||||||
int prim, void *buf, unsigned long used,
|
drm_mach64_vertex_t * vertex)
|
||||||
int discard)
|
|
||||||
{
|
{
|
||||||
drm_mach64_private_t *dev_priv = dev->dev_private;
|
drm_mach64_private_t *dev_priv = dev->dev_private;
|
||||||
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||||
drm_buf_t *copy_buf;
|
drm_buf_t *copy_buf;
|
||||||
|
void *buf = vertex->buf;
|
||||||
|
unsigned long used = vertex->used;
|
||||||
|
int ret = 0;
|
||||||
|
int i = 0;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
int verify_ret = 0;
|
int verify_ret = 0;
|
||||||
DMALOCALS;
|
DMALOCALS;
|
||||||
|
|
@ -559,100 +562,92 @@ static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev,
|
||||||
DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n",
|
DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n",
|
||||||
__FUNCTION__, buf, used, sarea_priv->nbox);
|
__FUNCTION__, buf, used, sarea_priv->nbox);
|
||||||
|
|
||||||
if (used) {
|
if (!used)
|
||||||
int ret = 0;
|
goto _vertex_done;
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
copy_buf = mach64_freelist_get(dev_priv);
|
copy_buf = mach64_freelist_get(dev_priv);
|
||||||
if (copy_buf == NULL) {
|
if (copy_buf == NULL) {
|
||||||
DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n",
|
DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
|
||||||
__FUNCTION__);
|
return DRM_ERR(EAGAIN);
|
||||||
return DRM_ERR(EAGAIN);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((verify_ret =
|
verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used);
|
||||||
copy_and_verify_from_user(GETBUFPTR(copy_buf), buf,
|
|
||||||
used)) == 0) {
|
|
||||||
|
|
||||||
copy_buf->used = used;
|
if (verify_ret != 0) {
|
||||||
|
mach64_freelist_put(dev_priv, copy_buf);
|
||||||
|
goto _vertex_done;
|
||||||
|
}
|
||||||
|
|
||||||
DMASETPTR(copy_buf);
|
copy_buf->used = used;
|
||||||
|
|
||||||
if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) {
|
DMASETPTR(copy_buf);
|
||||||
ret = mach64_emit_state(filp, dev_priv);
|
|
||||||
if (ret < 0)
|
if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) {
|
||||||
return ret;
|
ret = mach64_emit_state(filp, dev_priv);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Emit the next cliprect */
|
||||||
|
if (i < sarea_priv->nbox) {
|
||||||
|
ret = mach64_emit_cliprect(filp, dev_priv,
|
||||||
|
&sarea_priv->boxes[i]);
|
||||||
|
if (ret < 0) {
|
||||||
|
/* failed to get buffer */
|
||||||
|
return ret;
|
||||||
|
} else if (ret != 0) {
|
||||||
|
/* null intersection with scissor */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
/* Emit the next cliprect */
|
|
||||||
if (i < sarea_priv->nbox) {
|
|
||||||
ret =
|
|
||||||
mach64_emit_cliprect(filp, dev_priv,
|
|
||||||
&sarea_priv->
|
|
||||||
boxes[i]);
|
|
||||||
if (ret < 0) {
|
|
||||||
/* failed to get buffer */
|
|
||||||
return ret;
|
|
||||||
} else if (ret != 0) {
|
|
||||||
/* null intersection with scissor */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((i >= sarea_priv->nbox - 1))
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
/* Add the buffer to the DMA queue */
|
|
||||||
DMAADVANCE(dev_priv, done);
|
|
||||||
|
|
||||||
} while (++i < sarea_priv->nbox);
|
|
||||||
}
|
}
|
||||||
|
if ((i >= sarea_priv->nbox - 1))
|
||||||
|
done = 1;
|
||||||
|
|
||||||
if (copy_buf->pending && !done) {
|
/* Add the buffer to the DMA queue */
|
||||||
|
DMAADVANCE(dev_priv, done);
|
||||||
|
|
||||||
|
} while (++i < sarea_priv->nbox);
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
if (copy_buf->pending) {
|
||||||
DMADISCARDBUF();
|
DMADISCARDBUF();
|
||||||
} else if (!done) {
|
} else {
|
||||||
/* This buffer wasn't used (no cliprects or verify failed), so place it back
|
/* This buffer wasn't used (no cliprects), so place it
|
||||||
* on the free list
|
* back on the free list
|
||||||
*/
|
*/
|
||||||
struct list_head *ptr;
|
mach64_freelist_put(dev_priv, copy_buf);
|
||||||
drm_mach64_freelist_t *entry;
|
|
||||||
#if MACH64_EXTRA_CHECKING
|
|
||||||
list_for_each(ptr, &dev_priv->pending) {
|
|
||||||
entry =
|
|
||||||
list_entry(ptr, drm_mach64_freelist_t,
|
|
||||||
list);
|
|
||||||
if (copy_buf == entry->buf) {
|
|
||||||
DRM_ERROR
|
|
||||||
("%s: Trying to release a pending buf\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
return DRM_ERR(EFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ptr = dev_priv->placeholders.next;
|
|
||||||
entry = list_entry(ptr, drm_mach64_freelist_t, list);
|
|
||||||
copy_buf->pending = 0;
|
|
||||||
copy_buf->used = 0;
|
|
||||||
entry->buf = copy_buf;
|
|
||||||
entry->discard = 1;
|
|
||||||
list_del(ptr);
|
|
||||||
list_add_tail(ptr, &dev_priv->free_list);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_vertex_done:
|
||||||
sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS;
|
sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS;
|
||||||
sarea_priv->nbox = 0;
|
sarea_priv->nbox = 0;
|
||||||
|
|
||||||
return verify_ret;
|
return verify_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline__ int copy_from_user_blit(u32 *to,
|
||||||
|
const u32 __user *ufrom,
|
||||||
|
unsigned long bytes)
|
||||||
|
{
|
||||||
|
to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET);
|
||||||
|
|
||||||
|
if (DRM_COPY_FROM_USER(to, ufrom, bytes)) {
|
||||||
|
return DRM_ERR(EFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev,
|
static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev,
|
||||||
drm_mach64_blit_t * blit)
|
drm_mach64_blit_t * blit)
|
||||||
{
|
{
|
||||||
drm_mach64_private_t *dev_priv = dev->dev_private;
|
drm_mach64_private_t *dev_priv = dev->dev_private;
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
int dword_shift, dwords;
|
int dword_shift, dwords;
|
||||||
drm_buf_t *buf;
|
unsigned long used;
|
||||||
|
drm_buf_t *copy_buf;
|
||||||
|
int verify_ret = 0;
|
||||||
DMALOCALS;
|
DMALOCALS;
|
||||||
|
|
||||||
/* The compiler won't optimize away a division by a variable,
|
/* The compiler won't optimize away a division by a variable,
|
||||||
|
|
@ -679,34 +674,34 @@ static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev,
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dispatch the blit buffer.
|
|
||||||
*/
|
|
||||||
buf = dma->buflist[blit->idx];
|
|
||||||
|
|
||||||
if (buf->filp != filp) {
|
|
||||||
DRM_ERROR("process %d (filp %p) using buffer with filp %p\n",
|
|
||||||
DRM_CURRENTPID, filp, buf->filp);
|
|
||||||
return DRM_ERR(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->pending) {
|
|
||||||
DRM_ERROR("sending pending buffer %d\n", blit->idx);
|
|
||||||
return DRM_ERR(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set buf->used to the bytes of blit data based on the blit dimensions
|
/* Set buf->used to the bytes of blit data based on the blit dimensions
|
||||||
* and verify the size. When the setup is emitted to the buffer with
|
* and verify the size. When the setup is emitted to the buffer with
|
||||||
* the DMA* macros below, buf->used is incremented to include the bytes
|
* the DMA* macros below, buf->used is incremented to include the bytes
|
||||||
* used for setup as well as the blit data.
|
* used for setup as well as the blit data.
|
||||||
*/
|
*/
|
||||||
dwords = (blit->width * blit->height) >> dword_shift;
|
dwords = (blit->width * blit->height) >> dword_shift;
|
||||||
buf->used = dwords << 2;
|
used = dwords << 2;
|
||||||
if (buf->used <= 0 ||
|
if (used <= 0 ||
|
||||||
buf->used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) {
|
used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) {
|
||||||
DRM_ERROR("Invalid blit size: %d bytes\n", buf->used);
|
DRM_ERROR("Invalid blit size: %lu bytes\n", used);
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy_buf = mach64_freelist_get(dev_priv);
|
||||||
|
if (copy_buf == NULL) {
|
||||||
|
DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
|
||||||
|
return DRM_ERR(EAGAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used);
|
||||||
|
|
||||||
|
if (verify_ret != 0) {
|
||||||
|
mach64_freelist_put(dev_priv, copy_buf);
|
||||||
|
goto _blit_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_buf->used = used;
|
||||||
|
|
||||||
/* FIXME: Use a last buffer flag and reduce the state emitted for subsequent,
|
/* FIXME: Use a last buffer flag and reduce the state emitted for subsequent,
|
||||||
* continuation buffers?
|
* continuation buffers?
|
||||||
*/
|
*/
|
||||||
|
|
@ -715,7 +710,7 @@ static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev,
|
||||||
* a register command every 16 dwords. State setup is added at the start of the
|
* a register command every 16 dwords. State setup is added at the start of the
|
||||||
* buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET
|
* buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET
|
||||||
*/
|
*/
|
||||||
DMASETPTR(buf);
|
DMASETPTR(copy_buf);
|
||||||
|
|
||||||
DMAOUTREG(MACH64_Z_CNTL, 0);
|
DMAOUTREG(MACH64_Z_CNTL, 0);
|
||||||
DMAOUTREG(MACH64_SCALE_3D_CNTL, 0);
|
DMAOUTREG(MACH64_SCALE_3D_CNTL, 0);
|
||||||
|
|
@ -745,12 +740,13 @@ static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev,
|
||||||
DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x);
|
DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x);
|
||||||
DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width);
|
DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width);
|
||||||
|
|
||||||
DRM_DEBUG("%s: %d bytes\n", __FUNCTION__, buf->used);
|
DRM_DEBUG("%s: %lu bytes\n", __FUNCTION__, used);
|
||||||
|
|
||||||
/* Add the buffer to the queue */
|
/* Add the buffer to the queue */
|
||||||
DMAADVANCEHOSTDATA(dev_priv);
|
DMAADVANCEHOSTDATA(dev_priv);
|
||||||
|
|
||||||
return 0;
|
_blit_done:
|
||||||
|
return verify_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
|
|
@ -842,14 +838,12 @@ int mach64_dma_vertex(DRM_IOCTL_ARGS)
|
||||||
if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS)
|
if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS)
|
||||||
sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS;
|
sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS;
|
||||||
|
|
||||||
return mach64_dma_dispatch_vertex(filp, dev, vertex.prim, vertex.buf,
|
return mach64_dma_dispatch_vertex(filp, dev, &vertex);
|
||||||
vertex.used, vertex.discard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mach64_dma_blit(DRM_IOCTL_ARGS)
|
int mach64_dma_blit(DRM_IOCTL_ARGS)
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
drm_mach64_private_t *dev_priv = dev->dev_private;
|
drm_mach64_private_t *dev_priv = dev->dev_private;
|
||||||
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||||
drm_mach64_blit_t blit;
|
drm_mach64_blit_t blit;
|
||||||
|
|
@ -860,15 +854,6 @@ int mach64_dma_blit(DRM_IOCTL_ARGS)
|
||||||
DRM_COPY_FROM_USER_IOCTL(blit, (drm_mach64_blit_t *) data,
|
DRM_COPY_FROM_USER_IOCTL(blit, (drm_mach64_blit_t *) data,
|
||||||
sizeof(blit));
|
sizeof(blit));
|
||||||
|
|
||||||
DRM_DEBUG("%s: pid=%d index=%d\n",
|
|
||||||
__FUNCTION__, DRM_CURRENTPID, blit.idx);
|
|
||||||
|
|
||||||
if (blit.idx < 0 || blit.idx >= dma->buf_count) {
|
|
||||||
DRM_ERROR("buffer index %d (of %d max)\n",
|
|
||||||
blit.idx, dma->buf_count - 1);
|
|
||||||
return DRM_ERR(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mach64_dma_dispatch_blit(filp, dev, &blit);
|
ret = mach64_dma_dispatch_blit(filp, dev, &blit);
|
||||||
|
|
||||||
/* Make sure we restore the 3D state next time.
|
/* Make sure we restore the 3D state next time.
|
||||||
|
|
|
||||||
|
|
@ -538,6 +538,36 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
|
||||||
|
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||||
|
{
|
||||||
|
u32 *cmd = (u32 *) cmdbuf->buf;
|
||||||
|
int count, ret;
|
||||||
|
RING_LOCALS;
|
||||||
|
|
||||||
|
count=(cmd[0]>>16) & 0x3fff;
|
||||||
|
|
||||||
|
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
|
||||||
|
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
ret = r300_check_offset(dev_priv, cmd[2]);
|
||||||
|
if (ret) {
|
||||||
|
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_RING(count+2);
|
||||||
|
OUT_RING(cmd[0]);
|
||||||
|
OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
|
||||||
|
ADVANCE_RING();
|
||||||
|
|
||||||
|
cmdbuf->buf += (count+2)*4;
|
||||||
|
cmdbuf->bufsz -= (count+2)*4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
|
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
|
||||||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||||
{
|
{
|
||||||
|
|
@ -578,10 +608,11 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
|
||||||
case RADEON_CNTL_BITBLT_MULTI:
|
case RADEON_CNTL_BITBLT_MULTI:
|
||||||
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
|
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
|
||||||
|
|
||||||
|
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
||||||
|
return r300_emit_indx_buffer(dev_priv, cmdbuf);
|
||||||
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
||||||
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
||||||
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
||||||
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
|
||||||
case RADEON_WAIT_FOR_IDLE:
|
case RADEON_WAIT_FOR_IDLE:
|
||||||
case RADEON_CP_NOP:
|
case RADEON_CP_NOP:
|
||||||
/* these packets are safe */
|
/* these packets are safe */
|
||||||
|
|
|
||||||
|
|
@ -1130,7 +1130,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
|
||||||
| (dev_priv->fb_location >> 16));
|
| (dev_priv->fb_location >> 16));
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
|
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
|
||||||
RADEON_WRITE(RADEON_MC_AGP_LOCATION,
|
RADEON_WRITE(RADEON_MC_AGP_LOCATION,
|
||||||
(((dev_priv->gart_vm_start - 1 +
|
(((dev_priv->gart_vm_start - 1 +
|
||||||
|
|
@ -1158,7 +1158,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
|
||||||
dev_priv->ring.tail = cur_read_ptr;
|
dev_priv->ring.tail = cur_read_ptr;
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
|
RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
|
||||||
dev_priv->ring_rptr->offset
|
dev_priv->ring_rptr->offset
|
||||||
- dev->agp->base + dev_priv->gart_vm_start);
|
- dev->agp->base + dev_priv->gart_vm_start);
|
||||||
|
|
@ -1301,7 +1301,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
if (dev_priv->flags & CHIP_IS_PCIE) {
|
if (dev_priv->flags & RADEON_IS_PCIE) {
|
||||||
radeon_set_pciegart(dev_priv, on);
|
radeon_set_pciegart(dev_priv, on);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1339,26 +1339,26 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
/* if we require new memory map but we don't have it fail */
|
/* if we require new memory map but we don't have it fail */
|
||||||
if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap)
|
if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap)
|
||||||
{
|
{
|
||||||
DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
|
DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
|
||||||
radeon_do_cleanup_cp(dev);
|
radeon_do_cleanup_cp(dev);
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
|
if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP))
|
||||||
{
|
{
|
||||||
DRM_DEBUG("Forcing AGP card to PCI mode\n");
|
DRM_DEBUG("Forcing AGP card to PCI mode\n");
|
||||||
dev_priv->flags &= ~CHIP_IS_AGP;
|
dev_priv->flags &= ~RADEON_IS_AGP;
|
||||||
}
|
}
|
||||||
else if (!(dev_priv->flags & (CHIP_IS_AGP | CHIP_IS_PCI | CHIP_IS_PCIE))
|
else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
|
||||||
&& !init->is_pci)
|
&& !init->is_pci)
|
||||||
{
|
{
|
||||||
DRM_DEBUG("Restoring AGP flag\n");
|
DRM_DEBUG("Restoring AGP flag\n");
|
||||||
dev_priv->flags |= CHIP_IS_AGP;
|
dev_priv->flags |= RADEON_IS_AGP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
|
if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) {
|
||||||
DRM_ERROR("PCI GART memory not allocated!\n");
|
DRM_ERROR("PCI GART memory not allocated!\n");
|
||||||
radeon_do_cleanup_cp(dev);
|
radeon_do_cleanup_cp(dev);
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
|
|
@ -1501,7 +1501,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
init->sarea_priv_offset);
|
init->sarea_priv_offset);
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
drm_core_ioremap(dev_priv->cp_ring, dev);
|
drm_core_ioremap(dev_priv->cp_ring, dev);
|
||||||
drm_core_ioremap(dev_priv->ring_rptr, dev);
|
drm_core_ioremap(dev_priv->ring_rptr, dev);
|
||||||
drm_core_ioremap(dev->agp_buffer_map, dev);
|
drm_core_ioremap(dev->agp_buffer_map, dev);
|
||||||
|
|
@ -1560,7 +1560,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
* align it down.
|
* align it down.
|
||||||
*/
|
*/
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
base = dev->agp->base;
|
base = dev->agp->base;
|
||||||
/* Check if valid */
|
/* Check if valid */
|
||||||
if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
|
if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
|
||||||
|
|
@ -1590,7 +1590,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP)
|
if (dev_priv->flags & RADEON_IS_AGP)
|
||||||
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
|
dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
|
||||||
- dev->agp->base
|
- dev->agp->base
|
||||||
+ dev_priv->gart_vm_start);
|
+ dev_priv->gart_vm_start);
|
||||||
|
|
@ -1616,7 +1616,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
/* Turn off PCI GART */
|
/* Turn off PCI GART */
|
||||||
radeon_set_pcigart(dev_priv, 0);
|
radeon_set_pcigart(dev_priv, 0);
|
||||||
} else
|
} else
|
||||||
|
|
@ -1636,7 +1636,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
dev_priv->gart_info.mapping.handle;
|
dev_priv->gart_info.mapping.handle;
|
||||||
|
|
||||||
dev_priv->gart_info.is_pcie =
|
dev_priv->gart_info.is_pcie =
|
||||||
!!(dev_priv->flags & CHIP_IS_PCIE);
|
!!(dev_priv->flags & RADEON_IS_PCIE);
|
||||||
dev_priv->gart_info.gart_table_location =
|
dev_priv->gart_info.gart_table_location =
|
||||||
DRM_ATI_GART_FB;
|
DRM_ATI_GART_FB;
|
||||||
|
|
||||||
|
|
@ -1648,7 +1648,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||||
DRM_ATI_GART_MAIN;
|
DRM_ATI_GART_MAIN;
|
||||||
dev_priv->gart_info.addr = NULL;
|
dev_priv->gart_info.addr = NULL;
|
||||||
dev_priv->gart_info.bus_addr = 0;
|
dev_priv->gart_info.bus_addr = 0;
|
||||||
if (dev_priv->flags & CHIP_IS_PCIE) {
|
if (dev_priv->flags & RADEON_IS_PCIE) {
|
||||||
DRM_ERROR
|
DRM_ERROR
|
||||||
("Cannot use PCI Express without GART in FB memory\n");
|
("Cannot use PCI Express without GART in FB memory\n");
|
||||||
radeon_do_cleanup_cp(dev);
|
radeon_do_cleanup_cp(dev);
|
||||||
|
|
@ -1690,7 +1690,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
|
||||||
drm_irq_uninstall(dev);
|
drm_irq_uninstall(dev);
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
if (dev_priv->cp_ring != NULL) {
|
if (dev_priv->cp_ring != NULL) {
|
||||||
drm_core_ioremapfree(dev_priv->cp_ring, dev);
|
drm_core_ioremapfree(dev_priv->cp_ring, dev);
|
||||||
dev_priv->cp_ring = NULL;
|
dev_priv->cp_ring = NULL;
|
||||||
|
|
@ -1745,7 +1745,7 @@ static int radeon_do_resume_cp(drm_device_t * dev)
|
||||||
DRM_DEBUG("Starting radeon_do_resume_cp()\n");
|
DRM_DEBUG("Starting radeon_do_resume_cp()\n");
|
||||||
|
|
||||||
#if __OS_HAS_AGP
|
#if __OS_HAS_AGP
|
||||||
if (dev_priv->flags & CHIP_IS_AGP) {
|
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||||
/* Turn off PCI GART */
|
/* Turn off PCI GART */
|
||||||
radeon_set_pcigart(dev_priv, 0);
|
radeon_set_pcigart(dev_priv, 0);
|
||||||
} else
|
} else
|
||||||
|
|
@ -2194,7 +2194,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
|
||||||
dev->dev_private = (void *)dev_priv;
|
dev->dev_private = (void *)dev_priv;
|
||||||
dev_priv->flags = flags;
|
dev_priv->flags = flags;
|
||||||
|
|
||||||
switch (flags & CHIP_FAMILY_MASK) {
|
switch (flags & RADEON_FAMILY_MASK) {
|
||||||
case CHIP_R100:
|
case CHIP_R100:
|
||||||
case CHIP_RV200:
|
case CHIP_RV200:
|
||||||
case CHIP_R200:
|
case CHIP_R200:
|
||||||
|
|
@ -2202,7 +2202,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
|
||||||
case CHIP_R350:
|
case CHIP_R350:
|
||||||
case CHIP_R420:
|
case CHIP_R420:
|
||||||
case CHIP_RV410:
|
case CHIP_RV410:
|
||||||
dev_priv->flags |= CHIP_HAS_HIERZ;
|
dev_priv->flags |= RADEON_HAS_HIERZ;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* all other chips have no hierarchical z buffer */
|
/* all other chips have no hierarchical z buffer */
|
||||||
|
|
@ -2210,14 +2210,14 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drm_device_is_agp(dev))
|
if (drm_device_is_agp(dev))
|
||||||
dev_priv->flags |= CHIP_IS_AGP;
|
dev_priv->flags |= RADEON_IS_AGP;
|
||||||
else if (drm_device_is_pcie(dev))
|
else if (drm_device_is_pcie(dev))
|
||||||
dev_priv->flags |= CHIP_IS_PCIE;
|
dev_priv->flags |= RADEON_IS_PCIE;
|
||||||
else
|
else
|
||||||
dev_priv->flags |= CHIP_IS_PCI;
|
dev_priv->flags |= RADEON_IS_PCI;
|
||||||
|
|
||||||
DRM_DEBUG("%s card detected\n",
|
DRM_DEBUG("%s card detected\n",
|
||||||
((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
|
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,16 +134,16 @@ enum radeon_cp_microcode_version {
|
||||||
* Chip flags
|
* Chip flags
|
||||||
*/
|
*/
|
||||||
enum radeon_chip_flags {
|
enum radeon_chip_flags {
|
||||||
CHIP_FAMILY_MASK = 0x0000ffffUL,
|
RADEON_FAMILY_MASK = 0x0000ffffUL,
|
||||||
CHIP_FLAGS_MASK = 0xffff0000UL,
|
RADEON_FLAGS_MASK = 0xffff0000UL,
|
||||||
CHIP_IS_MOBILITY = 0x00010000UL,
|
RADEON_IS_MOBILITY = 0x00010000UL,
|
||||||
CHIP_IS_IGP = 0x00020000UL,
|
RADEON_IS_IGP = 0x00020000UL,
|
||||||
CHIP_SINGLE_CRTC = 0x00040000UL,
|
RADEON_SINGLE_CRTC = 0x00040000UL,
|
||||||
CHIP_IS_AGP = 0x00080000UL,
|
RADEON_IS_AGP = 0x00080000UL,
|
||||||
CHIP_HAS_HIERZ = 0x00100000UL,
|
RADEON_HAS_HIERZ = 0x00100000UL,
|
||||||
CHIP_IS_PCIE = 0x00200000UL,
|
RADEON_IS_PCIE = 0x00200000UL,
|
||||||
CHIP_NEW_MEMMAP = 0x00400000UL,
|
RADEON_NEW_MEMMAP = 0x00400000UL,
|
||||||
CHIP_IS_PCI = 0x00800000UL,
|
RADEON_IS_PCI = 0x00800000UL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
|
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
|
||||||
|
|
@ -423,6 +423,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||||
#define RADEON_RB3D_COLOROFFSET 0x1c40
|
#define RADEON_RB3D_COLOROFFSET 0x1c40
|
||||||
#define RADEON_RB3D_COLORPITCH 0x1c48
|
#define RADEON_RB3D_COLORPITCH 0x1c48
|
||||||
|
|
||||||
|
#define RADEON_SRC_X_Y 0x1590
|
||||||
|
|
||||||
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
|
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
|
||||||
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
|
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
|
||||||
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
|
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
|
||||||
|
|
@ -440,6 +442,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||||
# define RADEON_ROP3_S 0x00cc0000
|
# define RADEON_ROP3_S 0x00cc0000
|
||||||
# define RADEON_ROP3_P 0x00f00000
|
# define RADEON_ROP3_P 0x00f00000
|
||||||
#define RADEON_DP_WRITE_MASK 0x16cc
|
#define RADEON_DP_WRITE_MASK 0x16cc
|
||||||
|
#define RADEON_SRC_PITCH_OFFSET 0x1428
|
||||||
#define RADEON_DST_PITCH_OFFSET 0x142c
|
#define RADEON_DST_PITCH_OFFSET 0x142c
|
||||||
#define RADEON_DST_PITCH_OFFSET_C 0x1c80
|
#define RADEON_DST_PITCH_OFFSET_C 0x1c80
|
||||||
# define RADEON_DST_TILE_LINEAR (0 << 30)
|
# define RADEON_DST_TILE_LINEAR (0 << 30)
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,14 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case R200_EMIT_VAP_CTL: {
|
||||||
|
RING_LOCALS;
|
||||||
|
BEGIN_RING(2);
|
||||||
|
OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
|
||||||
|
ADVANCE_RING();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case RADEON_EMIT_RB3D_COLORPITCH:
|
case RADEON_EMIT_RB3D_COLORPITCH:
|
||||||
case RADEON_EMIT_RE_LINE_PATTERN:
|
case RADEON_EMIT_RE_LINE_PATTERN:
|
||||||
case RADEON_EMIT_SE_LINE_WIDTH:
|
case RADEON_EMIT_SE_LINE_WIDTH:
|
||||||
|
|
@ -201,7 +209,6 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
|
||||||
case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
|
case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
|
||||||
case R200_EMIT_TFACTOR_0:
|
case R200_EMIT_TFACTOR_0:
|
||||||
case R200_EMIT_VTX_FMT_0:
|
case R200_EMIT_VTX_FMT_0:
|
||||||
case R200_EMIT_VAP_CTL:
|
|
||||||
case R200_EMIT_MATRIX_SELECT_0:
|
case R200_EMIT_MATRIX_SELECT_0:
|
||||||
case R200_EMIT_TEX_PROC_CTL_2:
|
case R200_EMIT_TEX_PROC_CTL_2:
|
||||||
case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
|
case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
|
||||||
|
|
@ -268,6 +275,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
||||||
unsigned int *cmdsz)
|
unsigned int *cmdsz)
|
||||||
{
|
{
|
||||||
u32 *cmd = (u32 *) cmdbuf->buf;
|
u32 *cmd = (u32 *) cmdbuf->buf;
|
||||||
|
u32 offset, narrays;
|
||||||
|
int count, i, k;
|
||||||
|
|
||||||
*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
||||||
|
|
||||||
|
|
@ -281,10 +290,106 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check client state and fix it up if necessary */
|
switch(cmd[0] & 0xff00) {
|
||||||
if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */
|
/* XXX Are there old drivers needing other packets? */
|
||||||
u32 offset;
|
|
||||||
|
|
||||||
|
case RADEON_3D_DRAW_IMMD:
|
||||||
|
case RADEON_3D_DRAW_VBUF:
|
||||||
|
case RADEON_3D_DRAW_INDX:
|
||||||
|
case RADEON_WAIT_FOR_IDLE:
|
||||||
|
case RADEON_CP_NOP:
|
||||||
|
case RADEON_3D_CLEAR_ZMASK:
|
||||||
|
/* case RADEON_CP_NEXT_CHAR:
|
||||||
|
case RADEON_CP_PLY_NEXTSCAN:
|
||||||
|
case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
|
||||||
|
/* these packets are safe */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_CP_3D_DRAW_IMMD_2:
|
||||||
|
case RADEON_CP_3D_DRAW_VBUF_2:
|
||||||
|
case RADEON_CP_3D_DRAW_INDX_2:
|
||||||
|
case RADEON_3D_CLEAR_HIZ:
|
||||||
|
/* safe but r200 only */
|
||||||
|
if (dev_priv->microcode_version != UCODE_R200) {
|
||||||
|
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_3D_LOAD_VBPNTR:
|
||||||
|
count = (cmd[0] >> 16) & 0x3fff;
|
||||||
|
|
||||||
|
if (count > 18) { /* 12 arrays max */
|
||||||
|
DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
|
||||||
|
count);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* carefully check packet contents */
|
||||||
|
narrays = cmd[1] & ~0xc000;
|
||||||
|
k = 0;
|
||||||
|
i = 2;
|
||||||
|
while ((k < narrays) && (i < (count + 2))) {
|
||||||
|
i++; /* skip attribute field */
|
||||||
|
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
|
||||||
|
DRM_ERROR
|
||||||
|
("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
|
||||||
|
k, i);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
i++;
|
||||||
|
if (k == narrays)
|
||||||
|
break;
|
||||||
|
/* have one more to process, they come in pairs */
|
||||||
|
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
|
||||||
|
DRM_ERROR
|
||||||
|
("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
|
||||||
|
k, i);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
/* do the counts match what we expect ? */
|
||||||
|
if ((k != narrays) || (i != (count + 2))) {
|
||||||
|
DRM_ERROR
|
||||||
|
("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
|
||||||
|
k, i, narrays, count + 1);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_3D_RNDR_GEN_INDX_PRIM:
|
||||||
|
if (dev_priv->microcode_version != UCODE_R100) {
|
||||||
|
DRM_ERROR("Invalid 3d packet for r200-class chip\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) {
|
||||||
|
DRM_ERROR("Invalid rndr_gen_indx offset\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_CP_INDX_BUFFER:
|
||||||
|
if (dev_priv->microcode_version != UCODE_R200) {
|
||||||
|
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
|
||||||
|
DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) {
|
||||||
|
DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_CNTL_HOSTDATA_BLT:
|
||||||
|
case RADEON_CNTL_PAINT_MULTI:
|
||||||
|
case RADEON_CNTL_BITBLT_MULTI:
|
||||||
|
/* MSB of opcode: next DWORD GUI_CNTL */
|
||||||
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
|
||||||
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
|
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
|
||||||
offset = cmd[2] << 10;
|
offset = cmd[2] << 10;
|
||||||
|
|
@ -306,6 +411,11 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
||||||
}
|
}
|
||||||
cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
|
cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
|
||||||
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -861,7 +971,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
|
||||||
*/
|
*/
|
||||||
dev_priv->sarea_priv->ctx_owner = 0;
|
dev_priv->sarea_priv->ctx_owner = 0;
|
||||||
|
|
||||||
if ((dev_priv->flags & CHIP_HAS_HIERZ)
|
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||||
&& (flags & RADEON_USE_HIERZ)) {
|
&& (flags & RADEON_USE_HIERZ)) {
|
||||||
/* FIXME : reverse engineer that for Rx00 cards */
|
/* FIXME : reverse engineer that for Rx00 cards */
|
||||||
/* FIXME : the mask supposedly contains low-res z values. So can't set
|
/* FIXME : the mask supposedly contains low-res z values. So can't set
|
||||||
|
|
@ -906,7 +1016,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
|
||||||
for (i = 0; i < nbox; i++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
int tileoffset, nrtilesx, nrtilesy, j;
|
int tileoffset, nrtilesx, nrtilesy, j;
|
||||||
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
|
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
|
||||||
if ((dev_priv->flags & CHIP_HAS_HIERZ)
|
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||||
&& !(dev_priv->microcode_version == UCODE_R200)) {
|
&& !(dev_priv->microcode_version == UCODE_R200)) {
|
||||||
/* FIXME : figure this out for r200 (when hierz is enabled). Or
|
/* FIXME : figure this out for r200 (when hierz is enabled). Or
|
||||||
maybe r200 actually doesn't need to put the low-res z value into
|
maybe r200 actually doesn't need to put the low-res z value into
|
||||||
|
|
@ -990,7 +1100,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO don't always clear all hi-level z tiles */
|
/* TODO don't always clear all hi-level z tiles */
|
||||||
if ((dev_priv->flags & CHIP_HAS_HIERZ)
|
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||||
&& (dev_priv->microcode_version == UCODE_R200)
|
&& (dev_priv->microcode_version == UCODE_R200)
|
||||||
&& (flags & RADEON_USE_HIERZ))
|
&& (flags & RADEON_USE_HIERZ))
|
||||||
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
|
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
|
||||||
|
|
@ -1262,9 +1372,9 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
|
||||||
|
|
||||||
DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
|
DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
|
||||||
|
|
||||||
BEGIN_RING(7);
|
BEGIN_RING(9);
|
||||||
|
|
||||||
OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
|
OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
|
||||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||||
RADEON_GMC_BRUSH_NONE |
|
RADEON_GMC_BRUSH_NONE |
|
||||||
|
|
@ -1276,6 +1386,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
|
||||||
|
|
||||||
/* Make this work even if front & back are flipped:
|
/* Make this work even if front & back are flipped:
|
||||||
*/
|
*/
|
||||||
|
OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
|
||||||
if (dev_priv->current_page == 0) {
|
if (dev_priv->current_page == 0) {
|
||||||
OUT_RING(dev_priv->back_pitch_offset);
|
OUT_RING(dev_priv->back_pitch_offset);
|
||||||
OUT_RING(dev_priv->front_pitch_offset);
|
OUT_RING(dev_priv->front_pitch_offset);
|
||||||
|
|
@ -1284,6 +1395,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
|
||||||
OUT_RING(dev_priv->back_pitch_offset);
|
OUT_RING(dev_priv->back_pitch_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
|
||||||
OUT_RING((x << 16) | y);
|
OUT_RING((x << 16) | y);
|
||||||
OUT_RING((x << 16) | y);
|
OUT_RING((x << 16) | y);
|
||||||
OUT_RING((w << 16) | h);
|
OUT_RING((w << 16) | h);
|
||||||
|
|
@ -3031,9 +3143,9 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RADEON_PARAM_CARD_TYPE:
|
case RADEON_PARAM_CARD_TYPE:
|
||||||
if (dev_priv->flags & CHIP_IS_PCIE)
|
if (dev_priv->flags & RADEON_IS_PCIE)
|
||||||
value = RADEON_CARD_PCIE;
|
value = RADEON_CARD_PCIE;
|
||||||
else if (dev_priv->flags & CHIP_IS_AGP)
|
else if (dev_priv->flags & RADEON_IS_AGP)
|
||||||
value = RADEON_CARD_AGP;
|
value = RADEON_CARD_AGP;
|
||||||
else
|
else
|
||||||
value = RADEON_CARD_PCI;
|
value = RADEON_CARD_PCI;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue