/* these have to be filled in */
irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
void (*irq_preinstall) (struct drm_device * dev);
- void (*irq_postinstall) (struct drm_device * dev);
+ int (*irq_postinstall) (struct drm_device * dev);
void (*irq_uninstall) (struct drm_device * dev);
- void (*reclaim_buffers) (struct drm_device *dev, struct file * filp);
+ void (*reclaim_buffers) (struct drm_device *dev,
+ struct drm_file *file_priv);
void (*reclaim_buffers_locked) (struct drm_device *dev,
- struct file * filp);
+ struct drm_file *file_priv);
void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
- struct file * filp);
- unsigned long (*get_map_ofs) (drm_map_t * map);
+ struct drm_file *file_priv);
+ unsigned long (*get_map_ofs) (struct drm_map * map);
unsigned long (*get_reg_ofs) (struct drm_device * dev);
- void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
+ void (*set_version) (struct drm_device * dev, struct drm_set_version * sv);
struct drm_fence_driver *fence_driver;
struct drm_bo_driver *bo_driver;
#ifdef __alpha__
struct pci_controller *hose;
#endif
- drm_sg_mem_t *sg; /**< Scatter gather memory */
+ int num_crtcs; /**< Number of CRTCs on this device */
+ struct drm_sg_mem *sg; /**< Scatter gather memory */
void *dev_private; /**< device private data */
- drm_sigdata_t sigdata; /**< For block_all_signals */
+ struct drm_sigdata sigdata; /**< For block_all_signals */
sigset_t sigmask;
struct drm_driver *driver;
* DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
*/
- extern int drm_i_have_hw_lock(struct file *filp);
- extern int drm_kernel_take_hw_lock(struct file *filp);
+ extern int drm_i_have_hw_lock(struct drm_device *dev,
+ struct drm_file *file_priv);
/* Buffer management support (drm_bufs.h) */
- extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addbufs_fb (drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addmap(drm_device_t * dev, unsigned int offset,
- unsigned int size, drm_map_type_t type,
- drm_map_flags_t flags, drm_local_map_t ** map_ptr);
- extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
- extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
- extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_addbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_infobufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_markbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_freebufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_mapbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+ extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addbufs_fb (struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addmap(struct drm_device *dev, unsigned int offset,
+ unsigned int size, enum drm_map_type type,
+ enum drm_map_flags flags, drm_local_map_t ** map_ptr);
+ extern int drm_addmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map);
+ extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map);
+ extern int drm_rmmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_addbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_infobufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_markbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_freebufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_mapbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern int drm_order(unsigned long size);
- extern unsigned long drm_get_resource_start(drm_device_t *dev,
+ extern unsigned long drm_get_resource_start(struct drm_device *dev,
unsigned int resource);
- extern unsigned long drm_get_resource_len(drm_device_t *dev,
+ extern unsigned long drm_get_resource_len(struct drm_device *dev,
unsigned int resource);
+ extern struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
+ drm_local_map_t *map);
+
/* DMA support (drm_dma.h) */
- extern int drm_dma_setup(drm_device_t * dev);
- extern void drm_dma_takedown(drm_device_t * dev);
- extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf);
- extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
+ extern int drm_dma_setup(struct drm_device *dev);
+ extern void drm_dma_takedown(struct drm_device *dev);
+ extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);
+ extern void drm_core_reclaim_buffers(struct drm_device *dev,
+ struct drm_file *filp);
/* IRQ support (drm_irq.h) */
- extern int drm_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+ extern int drm_control(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
- extern int drm_irq_uninstall(drm_device_t *dev);
- extern void drm_driver_irq_preinstall(drm_device_t * dev);
- extern void drm_driver_irq_postinstall(drm_device_t * dev);
- extern void drm_driver_irq_uninstall(drm_device_t * dev);
-
- extern int drm_vblank_init(drm_device_t *dev, int num_crtcs);
- extern int drm_wait_vblank(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
- extern void drm_locked_tasklet(drm_device_t *dev, void(*func)(drm_device_t*));
- extern u32 drm_vblank_count(drm_device_t *dev, int crtc);
- extern void drm_update_vblank_count(drm_device_t *dev, int crtc);
- extern void drm_handle_vblank(drm_device_t *dev, int crtc);
- extern int drm_vblank_get(drm_device_t *dev, int crtc);
- extern void drm_vblank_put(drm_device_t *dev, int crtc);
+ extern int drm_irq_install(struct drm_device *dev);
+ extern int drm_irq_uninstall(struct drm_device *dev);
+ extern void drm_driver_irq_preinstall(struct drm_device *dev);
+ extern void drm_driver_irq_postinstall(struct drm_device *dev);
+ extern void drm_driver_irq_uninstall(struct drm_device *dev);
+
-extern int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
-extern void drm_vbl_send_signals(struct drm_device *dev);
++extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
++extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp);
++extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
+ extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
++extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
++extern void drm_update_vblank_count(struct drm_device *dev, int crtc);
++extern void drm_handle_vblank(struct drm_device *dev, int crtc);
++extern int drm_vblank_get(struct drm_device *dev, int crtc);
++extern void drm_vblank_put(struct drm_device *dev, int crtc);
+
+ /* Modesetting support */
- extern int drm_modeset_ctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
++extern int drm_modeset_ctl(struct drm_device *dev, void *data,
++ struct drm_file *file_priv);
/* AGP/GART support (drm_agpsupport.h) */
- extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
- extern int drm_agp_acquire(drm_device_t * dev);
- extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_release(drm_device_t *dev);
- extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
- extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
- extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
- extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
- extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
- extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
- extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
- extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+ extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
+ extern int drm_agp_acquire(struct drm_device *dev);
+ extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_release(struct drm_device *dev);
+ extern int drm_agp_release_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode);
+ extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info);
+ extern int drm_agp_info_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request);
+ extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request);
+ extern int drm_agp_free_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request);
+ extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request);
+ extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
extern DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type);
#else
#include "drmP.h"
#include "drm_core.h"
- static void drm_cleanup(drm_device_t * dev);
+ static void drm_cleanup(struct drm_device * dev);
int drm_fb_loaded = 0;
- static int drm_version(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+ static int drm_version(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/** Ioctl table */
- static drm_ioctl_desc_t drm_ioctls[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0},
- [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH},
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH},
-
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH},
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH},
+ static struct drm_ioctl_desc drm_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH},
+ DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH),
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
#if __OS_HAS_AGP
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 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_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
- [DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl,
- DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_MODESET_CTL)] = {drm_modeset_ctl, 0},
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+
- // DRM_IOCTL_DEF(DRM_IOCTL_BUFOBJ, drm_bo_ioctl, DRM_AUTH),
++ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
-
+ DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl,
+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl,
+ DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_REFERENCE, drm_fence_reference_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_UNREFERENCE, drm_fence_unreference_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_SIGNALED, drm_fence_signaled_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_FLUSH, drm_fence_flush_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_WAIT, drm_fence_wait_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_EMIT, drm_fence_emit_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FENCE_BUFFERS, drm_fence_buffers_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_CREATE, drm_bo_create_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_MAP, drm_bo_map_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
return 0;
}
- drm_device_t *dev = (drm_device_t *)arg;
+static void vblank_disable_fn(unsigned long arg)
+{
- int drm_vblank_init(drm_device_t *dev, int num_crtcs)
++ struct drm_device *dev = (struct drm_device *)arg;
+ int i;
+
+ for (i = 0; i < dev->num_crtcs; i++)
+ if (atomic_read(&dev->vblank_refcount[i]) == 0)
+ dev->driver->disable_vblank(dev, i);
+}
+
++int drm_vblank_init(struct drm_device *dev, int num_crtcs)
+{
+ int i, ret = -ENOMEM;
+
+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,\
+ (unsigned long)dev);
+ spin_lock_init(&dev->vbl_lock);
+ atomic_set(&dev->vbl_signal_pending, 0);
+ dev->num_crtcs = num_crtcs;
+
+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vbl_queue)
+ goto err;
+
+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vbl_sigs)
+ goto err;
+
+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->_vblank_count)
+ goto err;
+
+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_refcount)
+ goto err;
+
+ dev->last_vblank = drm_calloc(1, sizeof(u32) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->last_vblank)
+ goto err;
+
+ dev->vblank_premodeset = drm_calloc(1, sizeof(u32) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_premodeset)
+ goto err;
+
+ dev->vblank_offset = drm_calloc(1, sizeof(u32) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_offset)
+ goto err;
+
+ /* Zero per-crtc vblank stuff */
+ for (i = 0; i < num_crtcs; i++) {
+ init_waitqueue_head(&dev->vbl_queue[i]);
+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
+ atomic_set(&dev->_vblank_count[i], 0);
+ atomic_set(&dev->vblank_refcount[i], 0);
+ }
+
+ return 0;
+
+err:
+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
+ num_crtcs, DRM_MEM_DRIVER);
+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) *
+ num_crtcs, DRM_MEM_DRIVER);
+ drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * num_crtcs,
+ DRM_MEM_DRIVER);
+ return ret;
+}
+EXPORT_SYMBOL(drm_vblank_init);
+
/**
* Install IRQ handler.
*
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
* before and after the installation.
*/
- static int drm_irq_install(drm_device_t * dev)
+ int drm_irq_install(struct drm_device * dev)
{
- int ret;
+ int ret = 0;
unsigned long sh_flags = 0;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
}
/* After installing handler */
- dev->driver->irq_postinstall(dev);
+ ret = dev->driver->irq_postinstall(dev);
- return 0;
+ return ret;
}
+ EXPORT_SYMBOL(drm_irq_install);
/**
* Uninstall the IRQ handler.
}
/**
- u32 drm_vblank_count(drm_device_t *dev, int crtc)
+ * drm_vblank_count - retrieve "cooked" vblank counter value
+ * @dev: DRM device
+ * @crtc: which counter to retrieve
+ *
+ * Fetches the "cooked" vblank count value that represents the number of
+ * vblank events since the system was booted, including lost events due to
+ * modesetting activity.
+ */
- void drm_update_vblank_count(drm_device_t *dev, int crtc)
++u32 drm_vblank_count(struct drm_device *dev, int crtc)
+{
+ return atomic_read(&dev->_vblank_count[crtc]) +
+ dev->vblank_offset[crtc];
+}
+EXPORT_SYMBOL(drm_vblank_count);
+
+/**
+ * drm_update_vblank_count - update the master vblank counter
+ * @dev: DRM device
+ * @crtc: counter to update
+ *
+ * Call back into the driver to update the appropriate vblank counter
+ * (specified by @crtc). Deal with wraparound, if it occurred, and
+ * update the last read value so we can deal with wraparound on the next
+ * call if necessary.
+ */
- int drm_vblank_get(drm_device_t *dev, int crtc)
++void drm_update_vblank_count(struct drm_device *dev, int crtc)
+{
+ unsigned long irqflags;
+ u32 cur_vblank, diff;
+
+ /*
+ * Interrupts were disabled prior to this call, so deal with counter
+ * wrap if needed.
+ * NOTE! It's possible we lost a full dev->max_vblank_count events
+ * here if the register is small or we had vblank interrupts off for
+ * a long time.
+ */
+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ if (cur_vblank < dev->last_vblank[crtc]) {
+ diff = dev->max_vblank_count -
+ dev->last_vblank[crtc];
+ diff += cur_vblank;
+ } else {
+ diff = cur_vblank - dev->last_vblank[crtc];
+ }
+ dev->last_vblank[crtc] = cur_vblank;
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+
+ atomic_add(diff, &dev->_vblank_count[crtc]);
+}
+EXPORT_SYMBOL(drm_update_vblank_count);
+
+/**
+ * drm_vblank_get - get a reference count on vblank events
+ * @dev: DRM device
+ * @crtc: which CRTC to own
+ *
+ * Acquire a reference count on vblank events to avoid having them disabled
+ * while in use. Note callers will probably want to update the master counter
+ * using drm_update_vblank_count() above before calling this routine so that
+ * wakeups occur on the right vblank event.
+ *
+ * RETURNS
+ * Zero on success, nonzero on failure.
+ */
- void drm_vblank_put(drm_device_t *dev, int crtc)
++int drm_vblank_get(struct drm_device *dev, int crtc)
+{
+ int ret = 0;
+
+ /* Going from 0->1 means we have to enable interrupts again */
+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
+ ret = dev->driver->enable_vblank(dev, crtc);
+ if (ret)
+ atomic_dec(&dev->vblank_refcount[crtc]);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_vblank_get);
+
+/**
+ * drm_vblank_put - give up ownership of vblank events
+ * @dev: DRM device
+ * @crtc: which counter to give up
+ *
+ * Release ownership of a given vblank counter, turning off interrupts
+ * if possible.
+ */
- int drm_modeset_ctl(DRM_IOCTL_ARGS)
++void drm_vblank_put(struct drm_device *dev, int crtc)
+{
+ /* Last user schedules interrupt disable */
+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
+ mod_timer(&dev->vblank_disable_timer,
+ round_jiffies_relative(DRM_HZ));
+}
+EXPORT_SYMBOL(drm_vblank_put);
+
+/**
+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
+ * @DRM_IOCTL_ARGS: standard ioctl arguments
+ *
+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
+ * ioctls around modesetting so that any lost vblank events are accounted for.
+ */
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
++int drm_modeset_ctl(struct drm_device *dev, void *data,
++ struct drm_file *file_priv)
+{
+ drm_modeset_ctl_t __user *argp = (void __user *)data;
+ drm_modeset_ctl_t modeset;
+ int crtc, ret = 0;
+ u32 new;
+
+ if (copy_from_user(&modeset, argp, sizeof(modeset))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ crtc = modeset.arg;
+ if (crtc >= dev->num_crtcs) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ switch (modeset.cmd) {
+ case _DRM_PRE_MODESET:
+ dev->vblank_premodeset[crtc] =
+ dev->driver->get_vblank_counter(dev, crtc);
+ break;
+ case _DRM_POST_MODESET:
+ new = dev->driver->get_vblank_counter(dev, crtc);
+ dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+out:
+ return ret;
+}
+
+/**
* Wait for VBLANK.
*
* \param inode device inode.
*
* If a signal is not requested, then calls vblank_wait().
*/
- int drm_wait_vblank(DRM_IOCTL_ARGS)
-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
++int drm_wait_vblank(struct drm_device *dev, void *data,
++ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_wait_vblank_t __user *argp = (void __user *)data;
- drm_wait_vblank_t vblwait;
+ union drm_wait_vblank *vblwait = data;
struct timeval now;
int ret = 0;
- unsigned int flags, seq;
+ unsigned int flags, seq, crtc;
if ((!dev->irq) || (!dev->irq_enabled))
return -EINVAL;
return -EINVAL;
}
- flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+ flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
+ if (crtc >= dev->num_crtcs)
return -EINVAL;
- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
- : &dev->vbl_received);
+ drm_update_vblank_count(dev, crtc);
+ seq = drm_vblank_count(dev, crtc);
- switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
+ switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
case _DRM_VBLANK_RELATIVE:
- vblwait.request.sequence += seq;
- vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+ vblwait->request.sequence += seq;
+ vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
case _DRM_VBLANK_ABSOLUTE:
break;
default:
if (flags & _DRM_VBLANK_SIGNAL) {
unsigned long irqflags;
- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
- drm_vbl_sig_t *vbl_sig;
+ struct drm_vbl_sig *vbl_sig;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
return -EBUSY;
}
- dev->vbl_pending++;
-
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- vbl_sig = drm_calloc(1, sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER);
- if (!vbl_sig) {
- if (!
- (vbl_sig =
- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
++ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
++ DRM_MEM_DRIVER);
++ if (!vbl_sig)
return -ENOMEM;
- }
+
+ ret = drm_vblank_get(dev, crtc);
+ if (ret) {
- drm_free(vbl_sig, sizeof(drm_vbl_sig_t),
++ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
+ DRM_MEM_DRIVER);
+ return ret;
}
- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
+ atomic_inc(&dev->vbl_signal_pending);
- vbl_sig->sequence = vblwait.request.sequence;
- vbl_sig->info.si_signo = vblwait.request.signal;
+ vbl_sig->sequence = vblwait->request.sequence;
+ vbl_sig->info.si_signo = vblwait->request.signal;
vbl_sig->task = current;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- vblwait.reply.sequence = seq;
+ vblwait->reply.sequence = seq;
} else {
- 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 =
- dev->driver->vblank_wait(dev,
- &vblwait->request.sequence);
-
+ unsigned long cur_vblank;
+
+ ret = drm_vblank_get(dev, crtc);
+ if (ret)
+ return ret;
+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
+ (((cur_vblank = drm_vblank_count(dev, crtc))
- - vblwait.request.sequence) <= (1 << 23)));
++ - vblwait->request.sequence) <= (1 << 23)));
+ drm_vblank_put(dev, crtc);
do_gettimeofday(&now);
- vblwait.reply.tval_sec = now.tv_sec;
- vblwait.reply.tval_usec = now.tv_usec;
- vblwait.reply.sequence = cur_vblank;
++
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
++ vblwait->reply.sequence = cur_vblank;
}
done:
*
* If a signal is not requested, then calls vblank_wait().
*/
- static void drm_vbl_send_signals(drm_device_t * dev, int crtc)
-void drm_vbl_send_signals(struct drm_device * dev)
++static void drm_vbl_send_signals(struct drm_device * dev, int crtc)
{
- drm_vbl_sig_t *vbl_sig, *tmp;
++ struct drm_vbl_sig *vbl_sig, *tmp;
+ struct list_head *vbl_sigs;
+ unsigned int vbl_seq;
unsigned long flags;
- int i;
spin_lock_irqsave(&dev->vbl_lock, flags);
spin_unlock_irqrestore(&dev->vbl_lock, flags);
}
-EXPORT_SYMBOL(drm_vbl_send_signals);
+
+/**
+ * drm_handle_vblank - handle a vblank event
+ * @dev: DRM device
+ * @crtc: where this event occurred
+ *
+ * Drivers should call this routine in their vblank interrupt handlers to
+ * update the vblank counter and send any signals that may be pending.
+ */
- void drm_handle_vblank(drm_device_t *dev, int crtc)
++void drm_handle_vblank(struct drm_device *dev, int crtc)
+{
+ drm_update_vblank_count(dev, crtc);
+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
+ drm_vbl_send_signals(dev, crtc);
+}
+EXPORT_SYMBOL(drm_handle_vblank);
/**
* Tasklet wrapper function.
*/
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
- DRIVER_IRQ_VBL2,
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.load = i915_driver_load,
+ .unload = i915_driver_unload,
.firstopen = i915_driver_firstopen,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
+ .suspend = i915_suspend,
+ .resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
- .vblank_wait = i915_driver_vblank_wait,
- .vblank_wait2 = i915_driver_vblank_wait2,
+ .get_vblank_counter = i915_get_vblank_counter,
+ .enable_vblank = i915_enable_vblank,
+ .disable_vblank = i915_disable_vblank,
.irq_preinstall = i915_driver_irq_preinstall,
.irq_postinstall = i915_driver_irq_postinstall,
.irq_uninstall = i915_driver_irq_uninstall,
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
-- DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
-- DRIVER_IRQ_VBL,
++ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.preclose = r128_driver_preclose,
.lastclose = r128_driver_lastclose,
-- .vblank_wait = r128_driver_vblank_wait,
++ .get_vblank_counter = r128_get_vblank_counter,
++ .enable_vblank = r128_enable_vblank,
++ .disable_vblank = r128_disable_vblank,
.irq_preinstall = r128_driver_irq_preinstall,
.irq_postinstall = r128_driver_irq_postinstall,
.irq_uninstall = r128_driver_irq_uninstall,
*
* \sa drmWaitVBlank().
*/
- typedef union drm_wait_vblank {
+ union drm_wait_vblank {
struct drm_wait_vblank_request request;
struct drm_wait_vblank_reply reply;
- } drm_wait_vblank_t;
+ };
- drm_u64_t arg;
+typedef enum {
+ _DRM_PRE_MODESET = 1,
+ _DRM_POST_MODESET = 2,
+} drm_modeset_ctl_cmd_t;
+
+/**
+ * DRM_IOCTL_MODESET_CTL ioctl argument type
+ *
+ * \sa drmModesetCtl().
+ */
+typedef struct drm_modeset_ctl {
++ u64 arg;
+ drm_modeset_ctl_cmd_t cmd;
+} drm_modeset_ctl_t;
+
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
- #define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
- #define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
- #define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
- #define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
- #define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
- #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
-
- #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
- #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
-
- #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
+ #define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode)
+ #define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info)
+ #define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
+ #define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer)
+ #define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
+ #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
+
+ #define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, struct drm_scatter_gather)
+ #define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
+
+ #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+
+ #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
+
+ #define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg)
+ #define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg)
+ #define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg)
+ #define DRM_IOCTL_MM_UNLOCK DRM_IOWR(0xc3, struct drm_mm_type_arg)
+
+ #define DRM_IOCTL_FENCE_CREATE DRM_IOWR(0xc4, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_REFERENCE DRM_IOWR(0xc6, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_UNREFERENCE DRM_IOWR(0xc7, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_SIGNALED DRM_IOWR(0xc8, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_FLUSH DRM_IOWR(0xc9, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_WAIT DRM_IOWR(0xca, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_EMIT DRM_IOWR(0xcb, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_BUFFERS DRM_IOWR(0xcc, struct drm_fence_arg)
+
+ #define DRM_IOCTL_BO_CREATE DRM_IOWR(0xcd, struct drm_bo_create_arg)
+ #define DRM_IOCTL_BO_MAP DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg)
+ #define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
+ #define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg)
+ #define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
+ #define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
- #define DRM_IOCTL_FENCE DRM_IOWR(0x3b, drm_fence_arg_t)
- #define DRM_IOCTL_BUFOBJ DRM_IOWR(0x3d, drm_bo_arg_t)
- #define DRM_IOCTL_MM_INIT DRM_IOWR(0x3e, drm_mm_init_arg_t)
-
- #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t)
+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0xa0, drm_modeset_ctl_t)
+
/*@}*/
/**
extern int i915_driver_firstopen(struct drm_device *dev);
/* i915_irq.c */
- extern int i915_irq_emit(DRM_IOCTL_ARGS);
- extern int i915_irq_wait(DRM_IOCTL_ARGS);
+ extern int i915_irq_emit(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_irq_wait(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
- extern void i915_driver_irq_preinstall(drm_device_t * dev);
- extern int i915_driver_irq_postinstall(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_get(DRM_IOCTL_ARGS);
- extern int i915_emit_irq(drm_device_t * dev);
+ extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern void i915_driver_irq_postinstall(struct drm_device * dev);
++extern int i915_driver_irq_postinstall(struct drm_device * dev);
+ extern void i915_driver_irq_uninstall(struct drm_device * dev);
+ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_emit_irq(struct drm_device * dev);
-extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
-extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
++extern int i915_enable_vblank(struct drm_device *dev, int crtc);
++extern void i915_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
+ extern int i915_vblank_swap(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
+extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
- extern int i915_vblank_swap(DRM_IOCTL_ARGS);
- extern int i915_enable_vblank(drm_device_t *dev, int crtc);
- extern void i915_disable_vblank(drm_device_t *dev, int crtc);
- extern u32 i915_get_vblank_counter(drm_device_t *dev, int crtc);
/* i915_mem.c */
- extern int i915_mem_alloc(DRM_IOCTL_ARGS);
- extern int i915_mem_free(DRM_IOCTL_ARGS);
- extern int i915_mem_init_heap(DRM_IOCTL_ARGS);
- extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS);
+ extern int i915_mem_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_mem_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_mem_init_heap(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern void i915_mem_takedown(struct mem_block **heap);
- extern void i915_mem_release(drm_device_t * dev,
- DRMFILE filp, struct mem_block *heap);
+ extern void i915_mem_release(struct drm_device * dev,
+ struct drm_file *file_priv,
+ struct mem_block *heap);
#ifdef I915_HAVE_FENCE
/* i915_fence.c */
*
* This function will be called with the HW lock held.
*/
- static void i915_vblank_tasklet(drm_device_t *dev)
+ static void i915_vblank_tasklet(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- unsigned long irqflags;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
- unsigned counter[2] = { atomic_read(&dev->vbl_received),
- atomic_read(&dev->vbl_received2) };
+ unsigned counter[2];
- drm_drawable_info_t *drw;
+ struct drm_drawable_info *drw;
drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp, offsets[3];
u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
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);
- int crtc = vbl_swap->pipe;
- int pipe = i915_get_pipe(dev, vbl_swap->plane);
++ int crtc = i915_get_pipe(dev, vbl_swap->plane);
- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
- if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
++ if ((counter[crtc] - vbl_swap->sequence) > (1<<23))
continue;
list_del(list);
dev_priv->swaps_pending--;
+ drm_vblank_put(dev, crtc);
- spin_unlock(&dev_priv->swaps_lock);
- spin_lock(&dev->drw_lock);
+ DRM_SPINUNLOCK(&dev_priv->swaps_lock);
+ DRM_SPINLOCK(&dev->drw_lock);
drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
}
}
- u32 i915_get_vblank_counter(drm_device_t *dev, int crtc)
++u32 i915_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long high_frame = crtc ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
+ unsigned long low_frame = crtc ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
+ u32 high1, high2, low, count;
+
- if (!IS_I965G(dev))
- return 0;
-
+ /*
+ * High & low register fields aren't synchronized, so make sure
+ * we get a low value that's stable across two reads of the high
+ * register.
+ */
+ do {
+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+ PIPE_FRAME_LOW_SHIFT);
+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ } while (high1 != high2);
+
+ count = (high1 << 8) | low;
+
+ return count;
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
- drm_device_t *dev = (drm_device_t *) arg;
+ struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u16 temp;
u32 pipea_stats, pipeb_stats;
#endif
}
- if (!IS_I965G(dev)) {
- if (temp & VSYNC_PIPEA_FLAG)
- atomic_inc(&dev->_vblank_count[0]);
- if (temp & VSYNC_PIPEB_FLAG)
- atomic_inc(&dev->_vblank_count[1]);
- }
- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
- 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_vbl_send_signals(dev);
+ /*
+ * Use drm_update_vblank_counter here to deal with potential lost
+ * interrupts
+ */
+ if (temp & VSYNC_PIPEA_FLAG)
+ drm_handle_vblank(dev, 0);
+ if (temp & VSYNC_PIPEB_FLAG)
+ drm_handle_vblank(dev, 1);
+ if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
I915_WRITE(I915REG_PIPEASTAT,
return ret;
}
-static int i915_driver_vblank_do_wait(struct drm_device *dev,
- unsigned int *sequence,
- atomic_t *counter)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
-
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return -EINVAL;
- }
-
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1<<23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
-}
-
-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
-}
-
/* Needs the lock as it touches the ring.
*/
- int i915_irq_emit(DRM_IOCTL_ARGS)
+ int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_irq_emit_t emit;
+ drm_i915_irq_emit_t *emit = data;
int result;
- LOCK_TEST_WITH_RETURN(dev, filp);
+ LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
- DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_i915_irq_wait_t __user *) data,
- sizeof(irqwait));
-
- return i915_wait_irq(dev, irqwait.irq_seq);
+ return i915_wait_irq(dev, irqwait->irq_seq);
}
- int i915_enable_vblank(drm_device_t *dev, int crtc)
-static void i915_enable_interrupt (struct drm_device *dev)
++int i915_enable_vblank(struct drm_device *dev, int crtc)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-
- dev_priv->irq_enable_reg = USER_INT_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
+
- if (!IS_I965G(dev))
- return 0;
-
+ switch (crtc) {
+ case 0:
dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
+ break;
+ case 1:
dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
- void i915_disable_vblank(drm_device_t *dev, int crtc)
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+
+ return 0;
+}
+
- if (!IS_I965G(dev))
- return;
-
++void i915_disable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
- static void i915_enable_interrupt (drm_device_t *dev)
+ switch (crtc) {
+ case 0:
+ dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
+ break;
+ case 1:
+ dev_priv->irq_enable_reg &= ~VSYNC_PIPEB_FLAG;
+ break;
+ default:
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+}
+
++static void i915_enable_interrupt (struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ dev_priv->irq_enable_reg |= USER_INT_FLAG;
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
dev_priv->irq_enabled = 1;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
- DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
- sizeof(pipe));
-
- if (pipe.pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
+ 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);
+ __FUNCTION__, pipe->pipe);
+ return -EINVAL;
}
- dev_priv->vblank_pipe = pipe.pipe;
+ dev_priv->vblank_pipe = pipe->pipe;
- i915_enable_interrupt (dev);
-
return 0;
}
/**
* Schedule buffer swap at given vertical blank.
*/
- int i915_vblank_swap(DRM_IOCTL_ARGS)
+ int i915_vblank_swap(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_vblank_swap_t swap;
+ drm_i915_vblank_swap_t *swap = data;
drm_i915_vbl_swap_t *vbl_swap;
- unsigned int pipe, seqtype, curseq;
+ unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
+ int ret;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __func__);
if (!(dev_priv->vblank_pipe & (1 << pipe))) {
DRM_ERROR("Invalid pipe %d\n", pipe);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
- spin_lock_irqsave(&dev->drw_lock, irqflags);
+ DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags);
- if (!drm_get_drawable_info(dev, swap.drawable)) {
- spin_unlock_irqrestore(&dev->drw_lock, irqflags);
- DRM_DEBUG("Invalid drawable ID %d\n", swap.drawable);
- return DRM_ERR(EINVAL);
+ /* It makes no sense to schedule a swap for a drawable that doesn't have
+ * valid information at this point. E.g. this could mean that the X
+ * server is too old to push drawable information to the DRM, in which
+ * case all such swaps would become ineffective.
+ */
+ if (!drm_get_drawable_info(dev, swap->drawable)) {
+ DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
+ DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
+ return -EINVAL;
}
- spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+ DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
+ drm_update_vblank_count(dev, pipe);
+ curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
- swap.sequence += curseq;
+ swap->sequence += curseq;
- if ((curseq - swap.sequence) <= (1<<23)) {
- if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) {
- swap.sequence = curseq + 1;
+ 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);
+ return -EINVAL;
}
}
DRM_DEBUG("\n");
- vbl_swap->drw_id = swap.drawable;
- vbl_swap->pipe = pipe;
- vbl_swap->sequence = swap.sequence;
- vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP);
+ ret = drm_vblank_get(dev, pipe);
+ if (ret) {
+ drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+ return ret;
+ }
+
+ vbl_swap->drw_id = swap->drawable;
+ vbl_swap->plane = plane;
+ vbl_swap->sequence = swap->sequence;
+ vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
if (vbl_swap->flip)
- swap.sequence++;
+ swap->sequence++;
- spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
+ DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
dev_priv->swaps_pending++;
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
}
- int i915_driver_irq_postinstall(drm_device_t * dev)
-void i915_driver_irq_postinstall(struct drm_device * dev)
++int i915_driver_irq_postinstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int ret, num_pipes = 2;
- spin_lock_init(&dev_priv->swaps_lock);
+ DRM_SPININIT(&dev_priv->swaps_lock, "swap");
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
dev_priv->swaps_pending = 0;
- dev_priv->user_irq_lock = SPIN_LOCK_UNLOCKED;
+ DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
dev_priv->user_irq_refcount = 0;
+ dev_priv->irq_enable_reg = 0;
+
+ ret = drm_vblank_init(dev, num_pipes);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
- if (!IS_I965G(dev)) {
- dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG;
- I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
- }
-
i915_enable_interrupt(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
*/
I915_WRITE(I915REG_INSTPM, ( 1 << 5) | ( 1 << 21));
+ return 0;
}
- void i915_driver_irq_uninstall(drm_device_t * dev)
+ void i915_driver_irq_uninstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u16 temp;
extern int mga_warp_init(drm_mga_private_t * dev_priv);
/* mga_irq.c */
- extern int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence);
- extern int mga_enable_vblank(drm_device_t *dev, int crtc);
- extern void mga_disable_vblank(drm_device_t *dev, int crtc);
- extern u32 mga_get_vblank_counter(drm_device_t *dev, int crtc);
++extern int mga_enable_vblank(struct drm_device *dev, int crtc);
++extern void mga_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
+ extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
+ extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
- extern void mga_driver_irq_preinstall(drm_device_t * dev);
- extern int mga_driver_irq_postinstall(drm_device_t * dev);
- extern void mga_driver_irq_uninstall(drm_device_t * dev);
+ extern void mga_driver_irq_preinstall(struct drm_device * dev);
-extern void mga_driver_irq_postinstall(struct drm_device * dev);
++extern int mga_driver_irq_postinstall(struct drm_device * dev);
+ extern void mga_driver_irq_uninstall(struct drm_device * dev);
extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
#include "mga_drm.h"
#include "mga_drv.h"
- u32 mga_get_vblank_counter(drm_device_t *dev, int crtc)
++u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+
+ if (crtc != 0) {
+ return 0;
+ }
+
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
- drm_device_t *dev = (drm_device_t *) arg;
+ struct drm_device *dev = (struct drm_device *) arg;
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
int status;
int handled = 0;
handled = 1;
}
- if ( handled ) {
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
+ return (handled) ? IRQ_HANDLED : IRQ_NONE;
}
-
- int mga_enable_vblank(drm_device_t *dev, int crtc)
-int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int mga_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return 0;
+ }
- *sequence = cur_vblank;
+ MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ return 0;
+}
- return ret;
+
- void mga_disable_vblank(drm_device_t *dev, int crtc)
++void mga_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ }
+
+ /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
+ * a nice hardware counter that tracks the number of refreshes when
+ * the interrupt is disabled, and the kernel doesn't know the refresh
+ * rate to calculate an estimate.
+ */
+ /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
}
-
- int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence)
+ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
unsigned int cur_fence;
MGA_WRITE(MGA_ICLEAR, ~0);
}
- int mga_driver_irq_postinstall(drm_device_t * dev)
-void mga_driver_irq_postinstall(struct drm_device * dev)
++int mga_driver_irq_postinstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ int ret;
- DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
+ ret = drm_vblank_init(dev, 1);
+ if (ret)
+ return ret;
- /* Turn on vertical blank interrupt and soft trap interrupt. */
- MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
+
+ /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
+ * in mga_enable_vblank.
+ */
+ MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
+ return 0;
}
-
- void mga_driver_irq_uninstall(drm_device_t * dev)
+ void mga_driver_irq_uninstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
if (!dev_priv)
/* nouveau_irq.c */
extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
- extern void nouveau_irq_preinstall(drm_device_t*);
- extern void nouveau_irq_postinstall(drm_device_t*);
- extern void nouveau_irq_uninstall(drm_device_t*);
+ extern void nouveau_irq_preinstall(struct drm_device *);
-extern void nouveau_irq_postinstall(struct drm_device *);
++extern int nouveau_irq_postinstall(struct drm_device *);
+ extern void nouveau_irq_uninstall(struct drm_device *);
+
+ /* nouveau_sgdma.c */
+ extern int nouveau_sgdma_init(struct drm_device *);
+ extern void nouveau_sgdma_takedown(struct drm_device *);
+ extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
+ uint32_t *page);
+ extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+ extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
+ extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
+
+ /* nouveau_dma.c */
+ extern int nouveau_dma_channel_init(struct drm_device *);
+ extern void nouveau_dma_channel_takedown(struct drm_device *);
+ extern int nouveau_dma_wait(struct drm_device *, int size);
/* nv04_fb.c */
- extern int nv04_fb_init(drm_device_t *dev);
- extern void nv04_fb_takedown(drm_device_t *dev);
+ extern int nv04_fb_init(struct drm_device *);
+ extern void nv04_fb_takedown(struct drm_device *);
/* nv10_fb.c */
- extern int nv10_fb_init(drm_device_t *dev);
- extern void nv10_fb_takedown(drm_device_t *dev);
+ extern int nv10_fb_init(struct drm_device *);
+ extern void nv10_fb_takedown(struct drm_device *);
/* nv40_fb.c */
- extern int nv40_fb_init(drm_device_t *dev);
- extern void nv40_fb_takedown(drm_device_t *dev);
+ extern int nv40_fb_init(struct drm_device *);
+ extern void nv40_fb_takedown(struct drm_device *);
+
+ /* nv04_fifo.c */
+ extern int nv04_fifo_create_context(struct nouveau_channel *);
+ extern void nv04_fifo_destroy_context(struct nouveau_channel *);
+ extern int nv04_fifo_load_context(struct nouveau_channel *);
+ extern int nv04_fifo_save_context(struct nouveau_channel *);
+
+ /* nv10_fifo.c */
+ extern int nv10_fifo_create_context(struct nouveau_channel *);
+ extern void nv10_fifo_destroy_context(struct nouveau_channel *);
+ extern int nv10_fifo_load_context(struct nouveau_channel *);
+ extern int nv10_fifo_save_context(struct nouveau_channel *);
+
+ /* nv40_fifo.c */
+ extern int nv40_fifo_init(struct drm_device *);
+ extern int nv40_fifo_create_context(struct nouveau_channel *);
+ extern void nv40_fifo_destroy_context(struct nouveau_channel *);
+ extern int nv40_fifo_load_context(struct nouveau_channel *);
+ extern int nv40_fifo_save_context(struct nouveau_channel *);
+
+ /* nv50_fifo.c */
+ extern int nv50_fifo_init(struct drm_device *);
+ extern void nv50_fifo_takedown(struct drm_device *);
+ extern int nv50_fifo_create_context(struct nouveau_channel *);
+ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
+ extern int nv50_fifo_load_context(struct nouveau_channel *);
+ extern int nv50_fifo_save_context(struct nouveau_channel *);
/* nv04_graph.c */
- extern void nouveau_nv04_context_switch(drm_device_t *dev);
- extern int nv04_graph_init(drm_device_t *dev);
- extern void nv04_graph_takedown(drm_device_t *dev);
- extern int nv04_graph_context_create(drm_device_t *dev, int channel);
+ extern void nouveau_nv04_context_switch(struct drm_device *);
+ extern int nv04_graph_init(struct drm_device *);
+ extern void nv04_graph_takedown(struct drm_device *);
+ extern int nv04_graph_create_context(struct nouveau_channel *);
+ extern void nv04_graph_destroy_context(struct nouveau_channel *);
+ extern int nv04_graph_load_context(struct nouveau_channel *);
+ extern int nv04_graph_save_context(struct nouveau_channel *);
/* nv10_graph.c */
- extern void nouveau_nv10_context_switch(drm_device_t *dev);
- extern int nv10_graph_init(drm_device_t *dev);
- extern void nv10_graph_takedown(drm_device_t *dev);
- extern int nv10_graph_context_create(drm_device_t *dev, int channel);
+ extern void nouveau_nv10_context_switch(struct drm_device *);
+ extern int nv10_graph_init(struct drm_device *);
+ extern void nv10_graph_takedown(struct drm_device *);
+ extern int nv10_graph_create_context(struct nouveau_channel *);
+ extern void nv10_graph_destroy_context(struct nouveau_channel *);
+ extern int nv10_graph_load_context(struct nouveau_channel *);
+ extern int nv10_graph_save_context(struct nouveau_channel *);
/* nv20_graph.c */
- extern void nouveau_nv20_context_switch(drm_device_t *dev);
- extern int nv20_graph_init(drm_device_t *dev);
- extern void nv20_graph_takedown(drm_device_t *dev);
- extern int nv20_graph_context_create(drm_device_t *dev, int channel);
-
- /* nv30_graph.c */
- extern int nv30_graph_init(drm_device_t *dev);
- extern void nv30_graph_takedown(drm_device_t *dev);
- extern int nv30_graph_context_create(drm_device_t *dev, int channel);
+ extern int nv20_graph_create_context(struct nouveau_channel *);
+ extern void nv20_graph_destroy_context(struct nouveau_channel *);
+ extern int nv20_graph_load_context(struct nouveau_channel *);
+ extern int nv20_graph_save_context(struct nouveau_channel *);
+ extern int nv20_graph_init(struct drm_device *);
+ extern void nv20_graph_takedown(struct drm_device *);
+ extern int nv30_graph_init(struct drm_device *);
/* nv40_graph.c */
- extern int nv40_graph_init(drm_device_t *dev);
- extern void nv40_graph_takedown(drm_device_t *dev);
- extern int nv40_graph_context_create(drm_device_t *dev, int channel);
- extern void nv40_graph_context_save_current(drm_device_t *dev);
- extern void nv40_graph_context_restore(drm_device_t *dev, int channel);
+ extern int nv40_graph_init(struct drm_device *);
+ extern void nv40_graph_takedown(struct drm_device *);
+ extern int nv40_graph_create_context(struct nouveau_channel *);
+ extern void nv40_graph_destroy_context(struct nouveau_channel *);
+ extern int nv40_graph_load_context(struct nouveau_channel *);
+ extern int nv40_graph_save_context(struct nouveau_channel *);
+
+ /* nv50_graph.c */
+ extern int nv50_graph_init(struct drm_device *);
+ extern void nv50_graph_takedown(struct drm_device *);
+ extern int nv50_graph_create_context(struct nouveau_channel *);
+ extern void nv50_graph_destroy_context(struct nouveau_channel *);
+ extern int nv50_graph_load_context(struct nouveau_channel *);
+ extern int nv50_graph_save_context(struct nouveau_channel *);
+
+ /* nv04_instmem.c */
+ extern int nv04_instmem_init(struct drm_device *);
+ extern void nv04_instmem_takedown(struct drm_device *);
+ extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+ uint32_t *size);
+ extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+ extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+ extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+
+ /* nv50_instmem.c */
+ extern int nv50_instmem_init(struct drm_device *);
+ extern void nv50_instmem_takedown(struct drm_device *);
+ extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+ uint32_t *size);
+ extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+ extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+ extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
/* nv04_mc.c */
- extern int nv04_mc_init(drm_device_t *dev);
- extern void nv04_mc_takedown(drm_device_t *dev);
+ extern int nv04_mc_init(struct drm_device *);
+ extern void nv04_mc_takedown(struct drm_device *);
/* nv40_mc.c */
- extern int nv40_mc_init(drm_device_t *dev);
- extern void nv40_mc_takedown(drm_device_t *dev);
+ extern int nv40_mc_init(struct drm_device *);
+ extern void nv40_mc_takedown(struct drm_device *);
+
+ /* nv50_mc.c */
+ extern int nv50_mc_init(struct drm_device *);
+ extern void nv50_mc_takedown(struct drm_device *);
/* nv04_timer.c */
- extern int nv04_timer_init(drm_device_t *dev);
- extern void nv04_timer_takedown(drm_device_t *dev);
+ extern int nv04_timer_init(struct drm_device *);
+ extern uint64_t nv04_timer_read(struct drm_device *);
+ extern void nv04_timer_takedown(struct drm_device *);
- extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg);
+ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
#if defined(__powerpc__)
#define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) )
NV_WRITE(NV03_PMC_INTR_EN_0, 0);
}
- void nouveau_irq_postinstall(drm_device_t *dev)
-void
++int
+ nouveau_irq_postinstall(struct drm_device *dev)
{
- drm_nouveau_private_t *dev_priv = dev->dev_private;
-
- if (!dev_priv) {
- DRM_ERROR("AIII, no dev_priv\n");
- return;
- }
- if (!dev_priv->mmio) {
- DRM_ERROR("AIII, no dev_priv->mmio\n");
- return;
- }
-
- DRM_DEBUG("IRQ: postinst\n");
-
- /* Enable PFIFO error reporting */
- NV_WRITE(NV03_PFIFO_INTR_EN_0 ,
- NV_PFIFO_INTR_CACHE_ERROR |
- NV_PFIFO_INTR_RUNOUT |
- NV_PFIFO_INTR_RUNOUT_OVERFLOW |
- NV_PFIFO_INTR_DMA_PUSHER |
- NV_PFIFO_INTR_DMA_PT |
- NV_PFIFO_INTR_SEMAPHORE |
- NV_PFIFO_INTR_ACQUIRE_TIMEOUT
- );
- NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
-
- /* Enable PGRAPH interrupts */
- if (dev_priv->card_type<NV_40)
- NV_WRITE(NV03_PGRAPH_INTR_EN,
- NV_PGRAPH_INTR_NOTIFY |
- NV_PGRAPH_INTR_MISSING_HW |
- NV_PGRAPH_INTR_CONTEXT_SWITCH |
- NV_PGRAPH_INTR_BUFFER_NOTIFY |
- NV_PGRAPH_INTR_ERROR
- );
- else
- NV_WRITE(NV40_PGRAPH_INTR_EN,
- NV_PGRAPH_INTR_NOTIFY |
- NV_PGRAPH_INTR_MISSING_HW |
- NV_PGRAPH_INTR_CONTEXT_SWITCH |
- NV_PGRAPH_INTR_BUFFER_NOTIFY |
- NV_PGRAPH_INTR_ERROR
- );
- NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
-
- #if 0
- /* Enable CRTC0/1 interrupts */
- NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK);
- NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK);
- #endif
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
/* Master enable */
NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
++
++ return 0;
}
- void nouveau_irq_uninstall(drm_device_t *dev)
+ void
+ nouveau_irq_uninstall(struct drm_device *dev)
{
- drm_nouveau_private_t *dev_priv = dev->dev_private;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
- if (!dev_priv) {
- DRM_ERROR("AIII, no dev_priv\n");
- return;
- }
- if (!dev_priv->mmio) {
- DRM_ERROR("AIII, no dev_priv->mmio\n");
- return;
- }
-
- DRM_DEBUG("IRQ: uninst\n");
-
- /* Disable PFIFO interrupts */
- NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
- /* Disable PGRAPH interrupts */
- if (dev_priv->card_type<NV_40)
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
- else
- NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
- #if 0
- /* Disable CRTC0/1 interrupts */
- NV_WRITE(NV_CRTC0_INTEN, 0);
- NV_WRITE(NV_CRTC1_INTEN, 0);
- #endif
/* Master disable */
NV_WRITE(NV03_PMC_INTR_EN_0, 0);
}
u32 crtc_offset;
u32 crtc_offset_cntl;
++ atomic_t vbl_received;
++
u32 color_fmt;
unsigned int front_offset;
unsigned int front_pitch;
extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
- extern int r128_do_cleanup_cce(drm_device_t * dev);
-
- extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+ extern int r128_do_cleanup_cce(struct drm_device * dev);
-extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
-
++extern int r128_enable_vblank(struct drm_device *dev, int crtc);
++extern void r128_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
- extern void r128_driver_irq_preinstall(drm_device_t * dev);
- extern void r128_driver_irq_postinstall(drm_device_t * dev);
- extern void r128_driver_irq_uninstall(drm_device_t * dev);
- extern void r128_driver_lastclose(drm_device_t * dev);
- extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp);
+ extern void r128_driver_irq_preinstall(struct drm_device * dev);
-extern void r128_driver_irq_postinstall(struct drm_device * dev);
++extern int r128_driver_irq_postinstall(struct drm_device * dev);
+ extern void r128_driver_irq_uninstall(struct drm_device * dev);
+ extern void r128_driver_lastclose(struct drm_device * dev);
+ extern void r128_driver_preclose(struct drm_device * dev,
+ struct drm_file *file_priv);
extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
#include "r128_drm.h"
#include "r128_drv.h"
++u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
++{
++ const drm_r128_private_t *dev_priv = dev->dev_private;
++
++ if (crtc != 0)
++ return 0;
++
++ return atomic_read(&dev_priv->vbl_received);
++}
++
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
{
- drm_device_t *dev = (drm_device_t *) arg;
+ struct drm_device *dev = (struct drm_device *) arg;
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
int status;
/* VBLANK interrupt */
if (status & R128_CRTC_VBLANK_INT) {
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
-- atomic_inc(&dev->vbl_received);
-- DRM_WAKEUP(&dev->vbl_queue);
-- drm_vbl_send_signals(dev);
++ atomic_inc(&dev_priv->vbl_received);
++ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
- int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
-int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int r128_enable_vblank(struct drm_device *dev, int crtc)
{
-- unsigned int cur_vblank;
-- int ret = 0;
++ drm_r128_private_t *dev_priv = dev->dev_private;
-- /* Assume that the user has missed the current sequence number
-- * by about a day rather than she wants to wait for years
-- * using vertical blanks...
-- */
-- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
-- (((cur_vblank = atomic_read(&dev->vbl_received))
-- - *sequence) <= (1 << 23)));
++ if (crtc != 0) {
++ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
++ return -EINVAL;
++ }
-- *sequence = cur_vblank;
++ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
++ return 0;
++}
++
++void r128_disable_vblank(struct drm_device *dev, int crtc)
++{
++ if (crtc != 0)
++ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
-- return ret;
++ /*
++ * FIXME: implement proper interrupt disable by using the vblank
++ * counter register (if available)
++ *
++ * R128_WRITE(R128_GEN_INT_CNTL,
++ * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
++ */
}
- void r128_driver_irq_preinstall(drm_device_t * dev)
+ void r128_driver_irq_preinstall(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
- void r128_driver_irq_postinstall(drm_device_t * dev)
-void r128_driver_irq_postinstall(struct drm_device * dev)
++int r128_driver_irq_postinstall(struct drm_device * dev)
{
-- drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
--
-- /* Turn on VBL interrupt */
-- R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
++ return drm_vblank_init(dev, 1);
}
- void r128_driver_irq_uninstall(drm_device_t * dev)
+ void r128_driver_irq_uninstall(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
if (!dev_priv)
extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
- extern int radeon_mem_alloc(DRM_IOCTL_ARGS);
- extern int radeon_mem_free(DRM_IOCTL_ARGS);
- extern int radeon_mem_init_heap(DRM_IOCTL_ARGS);
+ extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern void radeon_mem_takedown(struct mem_block **heap);
- extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);
+ extern void radeon_mem_release(struct drm_file *file_priv,
+ struct mem_block *heap);
/* radeon_irq.c */
- extern int radeon_irq_emit(DRM_IOCTL_ARGS);
- extern int radeon_irq_wait(DRM_IOCTL_ARGS);
-
- extern void radeon_do_release(drm_device_t * dev);
- extern u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc);
- extern int radeon_enable_vblank(drm_device_t *dev, int crtc);
- extern void radeon_disable_vblank(drm_device_t *dev, int crtc);
+ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
+
+ extern void radeon_do_release(struct drm_device * dev);
-extern int radeon_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
-extern int radeon_driver_vblank_wait2(struct drm_device * dev,
- unsigned int *sequence);
++extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
++extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
++extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
++extern void radeon_do_release(struct drm_device * dev);
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
- extern void radeon_driver_irq_preinstall(drm_device_t * dev);
- extern int radeon_driver_irq_postinstall(drm_device_t * dev);
- extern void radeon_driver_irq_uninstall(drm_device_t * dev);
- extern int radeon_vblank_crtc_get(drm_device_t *dev);
- extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value);
+ extern void radeon_driver_irq_preinstall(struct drm_device * dev);
-extern void radeon_driver_irq_postinstall(struct drm_device * dev);
++extern int radeon_driver_irq_postinstall(struct drm_device * dev);
+ extern void radeon_driver_irq_uninstall(struct drm_device * dev);
+ extern int radeon_vblank_crtc_get(struct drm_device *dev);
+ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
extern int radeon_driver_unload(struct drm_device *dev);
#include "radeon_drm.h"
#include "radeon_drv.h"
- static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state)
-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
- u32 mask)
++static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
- u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->irq_enable_reg |= mask;
+ else
+ dev_priv->irq_enable_reg &= ~mask;
+
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
+}
+
- int radeon_enable_vblank(drm_device_t *dev, int crtc)
++int radeon_enable_vblank(struct drm_device *dev, int crtc)
+{
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
- return DRM_ERR(EINVAL);
++ return EINVAL;
+ }
+
+ return 0;
+}
+
- void radeon_disable_vblank(drm_device_t *dev, int crtc)
++void radeon_disable_vblank(struct drm_device *dev, int crtc)
+{
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+}
+
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv)
+{
+ u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
+ (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
+ RADEON_CRTC2_VBLANK_STAT);
+
if (irqs)
RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+
return irqs;
}
return ret;
}
- u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc)
-static int radeon_driver_vblank_do_wait(struct drm_device * dev,
- unsigned int *sequence,
- int crtc)
++u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
- int ack = 0;
- atomic_t *counter;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 crtc_cnt_reg, crtc_status_reg;
+
+ if (!dev_priv) {
+ DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
- if (crtc == DRM_RADEON_VBLANK_CRTC1) {
- counter = &dev->vbl_received;
- ack |= RADEON_CRTC_VBLANK_STAT;
- } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
- counter = &dev->vbl_received2;
- ack |= RADEON_CRTC2_VBLANK_STAT;
- } else
+ if (crtc == 0) {
+ crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
+ crtc_status_reg = RADEON_CRTC_STATUS;
+ } else if (crtc == 1) {
+ crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
+ crtc_status_reg = RADEON_CRTC2_STATUS;
- } else
- return 0;
++ } else {
+ return -EINVAL;
++ }
- radeon_acknowledge_irqs(dev_priv, ack);
-
- dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1 << 23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
-}
-
-int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
+ return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
}
/* Needs the lock as it touches the ring.
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
- DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
- sizeof(irqwait));
-
- return radeon_wait_irq(dev, irqwait.irq_seq);
+ return radeon_wait_irq(dev, irqwait->irq_seq);
}
-static void radeon_enable_interrupt(struct drm_device *dev)
-{
- drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
-
- dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
- dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
-
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
- dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
--
- RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
- dev_priv->irq_enabled = 1;
-}
--
/* drm_dma.h hooks
*/
- void radeon_driver_irq_preinstall(drm_device_t * dev)
+ void radeon_driver_irq_preinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
/* Clear bits if they're already high */
- radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ radeon_acknowledge_irqs(dev_priv);
}
- int radeon_driver_irq_postinstall(drm_device_t * dev)
-void radeon_driver_irq_postinstall(struct drm_device * dev)
++int radeon_driver_irq_postinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
- radeon_enable_interrupt(dev);
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0x001fffff;
+
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
+
+ return 0;
}
- void radeon_driver_irq_uninstall(drm_device_t * dev)
+ void radeon_driver_irq_uninstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value);
- return DRM_ERR(EINVAL);
+ return -EINVAL;
}
dev_priv->vblank_crtc = (unsigned int)value;
- radeon_enable_interrupt(dev);
return 0;
}
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
-- DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
++ DRIVER_IRQ_SHARED,
.load = via_driver_load,
.unload = via_driver_unload,
#ifndef VIA_HAVE_CORE_MM
.context_ctor = via_init_context,
#endif
.context_dtor = via_final_context,
-- .vblank_wait = via_driver_vblank_wait,
++ .get_vblank_counter = via_get_vblank_counter,
++ .enable_vblank = via_enable_vblank,
++ .disable_vblank = via_disable_vblank,
.irq_preinstall = via_driver_irq_preinstall,
.irq_postinstall = via_driver_irq_postinstall,
.irq_uninstall = via_driver_irq_uninstall,
struct timeval last_vblank;
int last_vblank_valid;
unsigned usec_per_vblank;
++ atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
- extern drm_ioctl_desc_t via_ioctls[];
+ extern struct drm_ioctl_desc via_ioctls[];
extern int via_max_ioctl;
- extern int via_fb_init(DRM_IOCTL_ARGS);
- extern int via_mem_alloc(DRM_IOCTL_ARGS);
- extern int via_mem_free(DRM_IOCTL_ARGS);
- extern int via_agp_init(DRM_IOCTL_ARGS);
- extern int via_map_init(DRM_IOCTL_ARGS);
- extern int via_decoder_futex(DRM_IOCTL_ARGS);
- extern int via_wait_irq(DRM_IOCTL_ARGS);
- extern int via_dma_blit_sync( DRM_IOCTL_ARGS );
- extern int via_dma_blit( DRM_IOCTL_ARGS );
-
- extern int via_driver_load(drm_device_t *dev, unsigned long chipset);
- extern int via_driver_unload(drm_device_t *dev);
- extern int via_final_context(drm_device_t * dev, int context);
-
- extern int via_do_cleanup_map(drm_device_t * dev);
- extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+ extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv );
+ extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv );
+
+ extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
+ extern int via_driver_unload(struct drm_device *dev);
+ extern int via_final_context(struct drm_device * dev, int context);
+
+ extern int via_do_cleanup_map(struct drm_device * dev);
-extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
++extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
++extern int via_enable_vblank(struct drm_device *dev, int crtc);
++extern void via_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
- extern void via_driver_irq_preinstall(drm_device_t * dev);
- extern void via_driver_irq_postinstall(drm_device_t * dev);
- extern void via_driver_irq_uninstall(drm_device_t * dev);
+ extern void via_driver_irq_preinstall(struct drm_device * dev);
-extern void via_driver_irq_postinstall(struct drm_device * dev);
++extern int via_driver_irq_postinstall(struct drm_device * dev);
+ extern void via_driver_irq_uninstall(struct drm_device * dev);
- extern int via_dma_cleanup(drm_device_t * dev);
+ extern int via_dma_cleanup(struct drm_device * dev);
extern void via_init_command_verifier(void);
- extern int via_driver_dma_quiescent(drm_device_t * dev);
+ extern int via_driver_dma_quiescent(struct drm_device * dev);
extern void via_init_futex(drm_via_private_t *dev_priv);
extern void via_cleanup_futex(drm_via_private_t *dev_priv);
extern void via_release_futex(drm_via_private_t *dev_priv, int context);
1000000 - (then->tv_usec - now->tv_usec);
}
++u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
++{
++ drm_via_private_t *dev_priv = dev->dev_private;
++ if (crtc != 0)
++ return 0;
++
++ return atomic_read(&dev_priv->vbl_received);
++}
++
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
{
- drm_device_t *dev = (drm_device_t *) arg;
+ struct drm_device *dev = (struct drm_device *) arg;
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
int handled = 0;
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
-- atomic_inc(&dev->vbl_received);
-- if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
++ atomic_inc(&dev_priv->vbl_received);
++ if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
#ifdef __linux__
do_gettimeofday(&cur_vblank);
#else
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
-- if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
++ if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
dev_priv->usec_per_vblank);
}
-- DRM_WAKEUP(&dev->vbl_queue);
-- drm_vbl_send_signals(dev);
++ drm_handle_vblank(dev, 0);
handled = 1;
}
}
}
- int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
-int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int via_enable_vblank(struct drm_device *dev, int crtc)
{
-- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
-- unsigned int cur_vblank;
-- int ret = 0;
++ drm_via_private_t *dev_priv = dev->dev_private;
++ u32 status;
-- DRM_DEBUG("viadrv_vblank_wait\n");
-- if (!dev_priv) {
-- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
++ if (crtc != 0) {
++ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
return -EINVAL;
}
-- viadrv_acknowledge_irqs(dev_priv);
++ status = VIA_READ(VIA_REG_INTERRUPT);
++ VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
++ return 0;
++}
-- /* Assume that the user has missed the current sequence number
-- * by about a day rather than she wants to wait for years
-- * using vertical blanks...
-- */
++void via_disable_vblank(struct drm_device *dev, int crtc)
++{
++ if (crtc != 0)
++ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
-- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
-- (((cur_vblank = atomic_read(&dev->vbl_received)) -
-- *sequence) <= (1 << 23)));
--
-- *sequence = cur_vblank;
-- return ret;
++ /*
++ * FIXME: implement proper interrupt disable by using the vblank
++ * counter register (if available).
++ */
}
static int
}
}
- void via_driver_irq_postinstall(drm_device_t * dev)
-void via_driver_irq_postinstall(struct drm_device * dev)
++int via_driver_irq_postinstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
DRM_DEBUG("via_driver_irq_postinstall\n");
-- if (dev_priv) {
-- status = VIA_READ(VIA_REG_INTERRUPT);
-- VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
-- | dev_priv->irq_enable_mask);
++ if (!dev_priv)
++ return -EINVAL;
-- /* Some magic, oh for some data sheets ! */
++ status = VIA_READ(VIA_REG_INTERRUPT);
++ VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
++ | dev_priv->irq_enable_mask);
-- VIA_WRITE8(0x83d4, 0x11);
-- VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
--
-- }
++ /* Some magic, oh for some data sheets ! */
++ VIA_WRITE8(0x83d4, 0x11);
++ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
++
++ return 0;
}
- void via_driver_irq_uninstall(drm_device_t * dev)
+ void via_driver_irq_uninstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;