45,8 → 45,6 |
#include <linux/mm.h> |
|
#include <linux/spinlock.h> |
#include <linux/wait.h> |
#include <linux/bug.h> |
#include <linux/mutex.h> |
#include <linux/pci.h> |
#include <linux/sched.h> |
110,6 → 108,12 |
* PRIME: used in the prime code. |
* This is the category used by the DRM_DEBUG_PRIME() macro. |
* |
* ATOMIC: used in the atomic code. |
* This is the category used by the DRM_DEBUG_ATOMIC() macro. |
* |
* VBL: used for verbose debug message in the vblank code |
* This is the category used by the DRM_DEBUG_VBL() macro. |
* |
* Enabling verbose debug messages is done through the drm.debug parameter, |
* each category being enabled by a bit. |
* |
117,7 → 121,7 |
* drm.debug=0x2 will enable DRIVER messages |
* drm.debug=0x3 will enable CORE and DRIVER messages |
* ... |
* drm.debug=0xf will enable all messages |
* drm.debug=0x3f will enable all messages |
* |
* An interesting feature is that it's possible to enable verbose logging at |
* run-time by echoing the debug value in its sysfs node: |
127,6 → 131,8 |
#define DRM_UT_DRIVER 0x02 |
#define DRM_UT_KMS 0x04 |
#define DRM_UT_PRIME 0x08 |
#define DRM_UT_ATOMIC 0x10 |
#define DRM_UT_VBL 0x20 |
|
extern __printf(2, 3) |
void drm_ut_debug_printk(const char *function_name, |
149,6 → 155,8 |
#define DRIVER_MODESET 0x2000 |
#define DRIVER_PRIME 0x4000 |
#define DRIVER_RENDER 0x8000 |
#define DRIVER_ATOMIC 0x10000 |
#define DRIVER_KMS_LEGACY_CONTEXT 0x20000 |
|
/***********************************************************************/ |
/** \name Macros to make printk easier */ |
161,7 → 169,7 |
* \param arg arguments |
*/ |
#define DRM_ERROR(fmt, ...) \ |
drm_err(fmt, ##__VA_ARGS__) |
printk("DRM Error" fmt, ##__VA_ARGS__) |
|
/** |
* Rate limited error output. Like DRM_ERROR() but won't flood the log. |
209,13 → 217,23 |
do { \ |
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##args); \ |
} while (0) |
#define DRM_DEBUG_ATOMIC(fmt, args...) \ |
do { \ |
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##args); \ |
} while (0) |
#define DRM_DEBUG_VBL(fmt, args...) \ |
do { \ |
printk(KERN_INFO "[" DRM_NAME "] " fmt, ##args); \ |
} while (0) |
|
#else |
#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0) |
#define DRM_DEBUG_KMS(fmt, args...) do { } while (0) |
#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0) |
#define DRM_DEBUG(fmt, arg...) do { } while (0) |
#define DRM_DEBUG_ATOMIC(fmt, args...) do { } while (0) |
#define DRM_DEBUG_VBL(fmt, args...) do { } while (0) |
#endif |
|
/*@}*/ |
|
/***********************************************************************/ |
252,7 → 270,6 |
unsigned int cmd; |
int flags; |
drm_ioctl_t *func; |
unsigned int cmd_drv; |
const char *name; |
}; |
|
262,7 → 279,12 |
*/ |
|
#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ |
[DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl} |
[DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \ |
.cmd = DRM_IOCTL_##ioctl, \ |
.func = _func, \ |
.flags = _flags, \ |
.name = #ioctl \ |
} |
|
/* Event queued up for userspace to read */ |
struct drm_pending_event { |
292,7 → 314,10 |
* in the plane list |
*/ |
unsigned universal_planes:1; |
/* true if client understands atomic properties */ |
unsigned atomic:1; |
struct list_head lhead; |
struct drm_minor *minor; |
unsigned long lock_count; |
|
/** Mapping of mm object handles to object pointers. */ |
313,6 → 338,10 |
struct list_head fbs; |
struct mutex fbs_lock; |
|
/** User-created blob properties; this retains a reference on the |
* property. */ |
struct list_head blobs; |
|
wait_queue_head_t event_wait; |
struct list_head event_list; |
int event_space; |
340,8 → 369,7 |
* @minor: Link back to minor char device we are master for. Immutable. |
* @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex. |
* @unique_len: Length of unique field. Protected by drm_global_mutex. |
* @magiclist: Hash of used authentication tokens. Protected by struct_mutex. |
* @magicfree: List of used authentication tokens. Protected by struct_mutex. |
* @magic_map: Map of used authentication tokens. Protected by struct_mutex. |
* @lock: DRI lock information. |
* @driver_priv: Pointer to driver-private information. |
*/ |
350,8 → 378,7 |
struct drm_minor *minor; |
char *unique; |
int unique_len; |
struct drm_open_hash magiclist; |
struct list_head magicfree; |
struct idr magic_map; |
struct drm_lock_data lock; |
void *driver_priv; |
}; |
383,7 → 410,7 |
/** |
* get_vblank_counter - get raw hardware vblank counter |
* @dev: DRM device |
* @crtc: counter to fetch |
* @pipe: counter to fetch |
* |
* Driver callback for fetching a raw hardware vblank counter for @crtc. |
* If a device doesn't have a hardware counter, the driver can simply |
397,12 → 424,12 |
* RETURNS |
* Raw vblank counter value. |
*/ |
u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); |
u32 (*get_vblank_counter) (struct drm_device *dev, unsigned int pipe); |
|
/** |
* enable_vblank - enable vblank interrupt events |
* @dev: DRM device |
* @crtc: which irq to enable |
* @pipe: which irq to enable |
* |
* Enable vblank interrupts for @crtc. If the device doesn't have |
* a hardware vblank counter, this routine should be a no-op, since |
412,19 → 439,33 |
* Zero on success, appropriate errno if the given @crtc's vblank |
* interrupt cannot be enabled. |
*/ |
int (*enable_vblank) (struct drm_device *dev, int crtc); |
int (*enable_vblank) (struct drm_device *dev, unsigned int pipe); |
|
/** |
* disable_vblank - disable vblank interrupt events |
* @dev: DRM device |
* @crtc: which irq to enable |
* @pipe: which irq to enable |
* |
* Disable vblank interrupts for @crtc. If the device doesn't have |
* a hardware vblank counter, this routine should be a no-op, since |
* interrupts will have to stay on to keep the count accurate. |
*/ |
void (*disable_vblank) (struct drm_device *dev, int crtc); |
void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); |
|
/** |
* Called by \c drm_device_is_agp. Typically used to determine if a |
* card is really attached to AGP or not. |
* |
* \param dev DRM device handle |
* |
* \returns |
* One of three values is returned depending on whether or not the |
* card is absolutely \b not AGP (return of 0), absolutely \b is AGP |
* (return of 1), or may or may not be AGP (return of 2). |
*/ |
int (*device_is_agp) (struct drm_device *dev); |
|
/** |
* Called by vblank timestamping code. |
* |
* Return the current display scanout position from a crtc, and an |
431,7 → 472,7 |
* optional accurate ktime_get timestamp of when position was measured. |
* |
* \param dev DRM device. |
* \param crtc Id of the crtc to query. |
* \param pipe Id of the crtc to query. |
* \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). |
* \param *vpos Target location for current vertical scanout position. |
* \param *hpos Target location for current horizontal scanout position. |
439,6 → 480,7 |
* scanout position query. Can be NULL to skip timestamp. |
* \param *etime Target location for timestamp taken immediately after |
* scanout position query. Can be NULL to skip timestamp. |
* \param mode Current display timings. |
* |
* Returns vpos as a positive number while in active scanout area. |
* Returns vpos as a negative number inside vblank, counting the number |
454,10 → 496,10 |
* but unknown small number of scanlines wrt. real scanout position. |
* |
*/ |
int (*get_scanout_position) (struct drm_device *dev, int crtc, |
unsigned int flags, |
int *vpos, int *hpos, void *stime, |
void *etime); |
int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, |
unsigned int flags, int *vpos, int *hpos, |
ktime_t *stime, ktime_t *etime, |
const struct drm_display_mode *mode); |
|
/** |
* Called by \c drm_get_last_vbltimestamp. Should return a precise |
473,7 → 515,7 |
* to the OpenML OML_sync_control extension specification. |
* |
* \param dev dev DRM device handle. |
* \param crtc crtc for which timestamp should be returned. |
* \param pipe crtc for which timestamp should be returned. |
* \param *max_error Maximum allowable timestamp error in nanoseconds. |
* Implementation should strive to provide timestamp |
* with an error of at most *max_error nanoseconds. |
489,7 → 531,7 |
* negative number on failure. A positive status code on success, |
* which describes how the vblank_time timestamp was computed. |
*/ |
int (*get_vblank_timestamp) (struct drm_device *dev, int crtc, |
int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, |
int *max_error, |
struct timeval *vblank_time, |
unsigned flags); |
548,7 → 590,7 |
struct drm_minor { |
int index; /**< Minor device number */ |
int type; /**< Control or render */ |
// struct device kdev; /**< Linux device */ |
struct device *kdev; /**< Linux device */ |
struct drm_device *dev; |
|
struct dentry *debugfs_root; |
558,13 → 600,12 |
|
/* currently active master for this node. Protected by master_mutex */ |
struct drm_master *master; |
struct drm_mode_group mode_group; |
}; |
|
|
struct drm_pending_vblank_event { |
struct drm_pending_event base; |
int pipe; |
unsigned int pipe; |
struct drm_event_vblank event; |
}; |
|
571,15 → 612,21 |
struct drm_vblank_crtc { |
struct drm_device *dev; /* pointer to the drm_device */ |
wait_queue_head_t queue; /**< VBLANK wait queue */ |
struct timeval time[DRM_VBLANKTIME_RBSIZE]; /**< timestamp of current count */ |
struct timer_list disable_timer; /* delayed disable timer */ |
atomic_t count; /**< number of VBLANK interrupts */ |
|
/* vblank counter, protected by dev->vblank_time_lock for writes */ |
u32 count; |
/* vblank timestamps, protected by dev->vblank_time_lock for writes */ |
struct timeval time[DRM_VBLANKTIME_RBSIZE]; |
|
atomic_t refcount; /* number of users of vblank interruptsper crtc */ |
u32 last; /* protected by dev->vbl_lock, used */ |
/* for wraparound handling */ |
u32 last_wait; /* Last vblank seqno waited per CRTC */ |
unsigned int inmodeset; /* Display driver is setting mode */ |
int crtc; /* crtc index */ |
unsigned int pipe; /* crtc index */ |
int framedur_ns; /* frame/field duration in ns */ |
int linedur_ns; /* line duration in ns */ |
bool enabled; /* so we don't call enable more than |
once per disable */ |
}; |
598,7 → 645,9 |
struct device *dev; /**< Device structure of bus-device */ |
struct drm_driver *driver; /**< DRM driver managing the device */ |
void *dev_private; /**< DRM driver private data */ |
struct drm_minor *control; /**< Control node */ |
struct drm_minor *primary; /**< Primary node */ |
struct drm_minor *render; /**< Render node */ |
atomic_t unplugged; /**< Flag whether dev is dead */ |
/** \name Locks */ |
/*@{ */ |
638,8 → 687,6 |
|
/** \name Context support */ |
/*@{ */ |
bool irq_enabled; /**< True if irq handler is enabled */ |
int irq; |
|
__volatile__ long context_flag; /**< Context swapping flag */ |
int last_context; /**< Last current context */ |
647,6 → 694,8 |
|
/** \name VBLANK IRQ support */ |
/*@{ */ |
bool irq_enabled; |
int irq; |
|
/* |
* At load time, disabling the vblank interrupt won't be allowed since |
734,6 → 783,7 |
/*@{*/ |
|
/* Driver support (drm_drv.h) */ |
extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); |
extern long drm_ioctl(struct file *filp, |
unsigned int cmd, unsigned long arg); |
extern long drm_compat_ioctl(struct file *filp, |
745,6 → 795,7 |
extern ssize_t drm_read(struct file *filp, char __user *buffer, |
size_t count, loff_t *offset); |
extern int drm_release(struct inode *inode, struct file *filp); |
extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); |
|
/* Mapping support (drm_vm.h) */ |
extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); |
752,6 → 803,8 |
/* Misc. IOCTL support (drm_ioctl.c) */ |
int drm_noop(struct drm_device *dev, void *data, |
struct drm_file *file_priv); |
int drm_invalid_op(struct drm_device *dev, void *data, |
struct drm_file *file_priv); |
|
/* Cache management (drm_cache.c) */ |
void drm_clflush_pages(struct page *pages[], unsigned long num_pages); |
767,32 → 820,39 |
extern int drm_irq_install(struct drm_device *dev, int irq); |
extern int drm_irq_uninstall(struct drm_device *dev); |
|
extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); |
extern int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); |
extern int drm_wait_vblank(struct drm_device *dev, void *data, |
struct drm_file *filp); |
extern u32 drm_vblank_count(struct drm_device *dev, int crtc); |
extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, |
extern u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe); |
extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); |
extern u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, |
struct timeval *vblanktime); |
extern void drm_send_vblank_event(struct drm_device *dev, int crtc, |
extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, |
struct timeval *vblanktime); |
extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe, |
struct drm_pending_vblank_event *e); |
extern bool 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); |
extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, |
struct drm_pending_vblank_event *e); |
extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); |
extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); |
extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe); |
extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe); |
extern int drm_crtc_vblank_get(struct drm_crtc *crtc); |
extern void drm_crtc_vblank_put(struct drm_crtc *crtc); |
extern void drm_wait_one_vblank(struct drm_device *dev, int crtc); |
extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); |
extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); |
extern void drm_vblank_off(struct drm_device *dev, int crtc); |
extern void drm_vblank_on(struct drm_device *dev, int crtc); |
extern void drm_vblank_off(struct drm_device *dev, unsigned int pipe); |
extern void drm_vblank_on(struct drm_device *dev, unsigned int pipe); |
extern void drm_crtc_vblank_off(struct drm_crtc *crtc); |
extern void drm_crtc_vblank_reset(struct drm_crtc *crtc); |
extern void drm_crtc_vblank_on(struct drm_crtc *crtc); |
extern void drm_vblank_cleanup(struct drm_device *dev); |
extern u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe); |
|
extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, |
int crtc, int *max_error, |
unsigned int pipe, int *max_error, |
struct timeval *vblank_time, |
unsigned flags, |
const struct drm_crtc *refcrtc, |
const struct drm_display_mode *mode); |
extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, |
const struct drm_display_mode *mode); |
810,8 → 870,8 |
} |
|
/* Modesetting support */ |
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); |
extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc); |
extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe); |
extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe); |
|
/* Stub support (drm_stub.h) */ |
extern struct drm_master *drm_master_get(struct drm_master *master); |
820,6 → 880,7 |
extern void drm_put_dev(struct drm_device *dev); |
extern void drm_unplug_dev(struct drm_device *dev); |
extern unsigned int drm_debug; |
extern bool drm_atomic; |
|
/* Debugfs support */ |
#if defined(CONFIG_DEBUG_FS) |