/drivers/include/drm/drmP.h |
---|
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) |
/drivers/include/drm/drm_agpsupport.h |
---|
12,9 → 12,6 |
struct drm_device; |
struct drm_file; |
#define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && \ |
defined(MODULE))) |
struct drm_agp_head { |
struct agp_kern_info agp_info; |
struct list_head memory; |
28,7 → 25,7 |
unsigned long page_mask; |
}; |
#if __OS_HAS_AGP |
#if IS_ENABLED(CONFIG_AGP) |
void drm_free_agp(struct agp_memory * handle, int pages); |
int drm_bind_agp(struct agp_memory * handle, unsigned int start); |
66,7 → 63,7 |
int drm_agp_bind_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv); |
#else /* __OS_HAS_AGP */ |
#else /* CONFIG_AGP */ |
static inline void drm_free_agp(struct agp_memory * handle, int pages) |
{ |
105,23 → 102,11 |
return -ENODEV; |
} |
static inline int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_release(struct drm_device *dev) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_release_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_enable(struct drm_device *dev, |
struct drm_agp_mode mode) |
{ |
128,12 → 113,6 |
return -ENODEV; |
} |
static inline int drm_agp_enable_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_info(struct drm_device *dev, |
struct drm_agp_info *info) |
{ |
140,12 → 119,6 |
return -ENODEV; |
} |
static inline int drm_agp_info_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_alloc(struct drm_device *dev, |
struct drm_agp_buffer *request) |
{ |
152,12 → 125,6 |
return -ENODEV; |
} |
static inline int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_free(struct drm_device *dev, |
struct drm_agp_buffer *request) |
{ |
164,12 → 131,6 |
return -ENODEV; |
} |
static inline int drm_agp_free_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_unbind(struct drm_device *dev, |
struct drm_agp_binding *request) |
{ |
176,12 → 137,6 |
return -ENODEV; |
} |
static inline int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
static inline int drm_agp_bind(struct drm_device *dev, |
struct drm_agp_binding *request) |
{ |
188,12 → 143,6 |
return -ENODEV; |
} |
static inline int drm_agp_bind_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file_priv) |
{ |
return -ENODEV; |
} |
#endif /* CONFIG_AGP */ |
#endif /* __OS_HAS_AGP */ |
#endif /* _DRM_AGPSUPPORT_H_ */ |
/drivers/include/drm/drm_atomic.h |
---|
35,19 → 35,89 |
void drm_atomic_state_clear(struct drm_atomic_state *state); |
void drm_atomic_state_free(struct drm_atomic_state *state); |
int __must_check |
drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); |
void drm_atomic_state_default_clear(struct drm_atomic_state *state); |
void drm_atomic_state_default_release(struct drm_atomic_state *state); |
struct drm_crtc_state * __must_check |
drm_atomic_get_crtc_state(struct drm_atomic_state *state, |
struct drm_crtc *crtc); |
int drm_atomic_crtc_set_property(struct drm_crtc *crtc, |
struct drm_crtc_state *state, struct drm_property *property, |
uint64_t val); |
struct drm_plane_state * __must_check |
drm_atomic_get_plane_state(struct drm_atomic_state *state, |
struct drm_plane *plane); |
int drm_atomic_plane_set_property(struct drm_plane *plane, |
struct drm_plane_state *state, struct drm_property *property, |
uint64_t val); |
struct drm_connector_state * __must_check |
drm_atomic_get_connector_state(struct drm_atomic_state *state, |
struct drm_connector *connector); |
int drm_atomic_connector_set_property(struct drm_connector *connector, |
struct drm_connector_state *state, struct drm_property *property, |
uint64_t val); |
/** |
* drm_atomic_get_existing_crtc_state - get crtc state, if it exists |
* @state: global atomic state object |
* @crtc: crtc to grab |
* |
* This function returns the crtc state for the given crtc, or NULL |
* if the crtc is not part of the global atomic state. |
*/ |
static inline struct drm_crtc_state * |
drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state, |
struct drm_crtc *crtc) |
{ |
return state->crtc_states[drm_crtc_index(crtc)]; |
} |
/** |
* drm_atomic_get_existing_plane_state - get plane state, if it exists |
* @state: global atomic state object |
* @plane: plane to grab |
* |
* This function returns the plane state for the given plane, or NULL |
* if the plane is not part of the global atomic state. |
*/ |
static inline struct drm_plane_state * |
drm_atomic_get_existing_plane_state(struct drm_atomic_state *state, |
struct drm_plane *plane) |
{ |
return state->plane_states[drm_plane_index(plane)]; |
} |
/** |
* drm_atomic_get_existing_connector_state - get connector state, if it exists |
* @state: global atomic state object |
* @connector: connector to grab |
* |
* This function returns the connector state for the given connector, |
* or NULL if the connector is not part of the global atomic state. |
*/ |
static inline struct drm_connector_state * |
drm_atomic_get_existing_connector_state(struct drm_atomic_state *state, |
struct drm_connector *connector) |
{ |
int index = drm_connector_index(connector); |
if (index >= state->num_connector) |
return NULL; |
return state->connector_states[index]; |
} |
int __must_check |
drm_atomic_set_crtc_for_plane(struct drm_atomic_state *state, |
struct drm_plane *plane, struct drm_crtc *crtc); |
drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, |
struct drm_display_mode *mode); |
int __must_check |
drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, |
struct drm_property_blob *blob); |
int __must_check |
drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, |
struct drm_crtc *crtc); |
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, |
struct drm_framebuffer *fb); |
int __must_check |
56,6 → 126,10 |
int __must_check |
drm_atomic_add_affected_connectors(struct drm_atomic_state *state, |
struct drm_crtc *crtc); |
int __must_check |
drm_atomic_add_affected_planes(struct drm_atomic_state *state, |
struct drm_crtc *crtc); |
int |
drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, |
struct drm_crtc *crtc); |
62,8 → 136,42 |
void drm_atomic_legacy_backoff(struct drm_atomic_state *state); |
void |
drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret); |
int __must_check drm_atomic_check_only(struct drm_atomic_state *state); |
int __must_check drm_atomic_commit(struct drm_atomic_state *state); |
int __must_check drm_atomic_async_commit(struct drm_atomic_state *state); |
#define for_each_connector_in_state(state, connector, connector_state, __i) \ |
for ((__i) = 0; \ |
(__i) < (state)->num_connector && \ |
((connector) = (state)->connectors[__i], \ |
(connector_state) = (state)->connector_states[__i], 1); \ |
(__i)++) \ |
if (connector) |
#define for_each_crtc_in_state(state, crtc, crtc_state, __i) \ |
for ((__i) = 0; \ |
(__i) < (state)->dev->mode_config.num_crtc && \ |
((crtc) = (state)->crtcs[__i], \ |
(crtc_state) = (state)->crtc_states[__i], 1); \ |
(__i)++) \ |
if (crtc_state) |
#define for_each_plane_in_state(state, plane, plane_state, __i) \ |
for ((__i) = 0; \ |
(__i) < (state)->dev->mode_config.num_total_plane && \ |
((plane) = (state)->planes[__i], \ |
(plane_state) = (state)->plane_states[__i], 1); \ |
(__i)++) \ |
if (plane_state) |
static inline bool |
drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) |
{ |
return state->mode_changed || state->active_changed || |
state->connectors_changed; |
} |
#endif /* DRM_ATOMIC_H_ */ |
/drivers/include/drm/drm_atomic_helper.h |
---|
30,6 → 30,12 |
#include <drm/drm_crtc.h> |
struct drm_atomic_state; |
int drm_atomic_helper_check_modeset(struct drm_device *dev, |
struct drm_atomic_state *state); |
int drm_atomic_helper_check_planes(struct drm_device *dev, |
struct drm_atomic_state *state); |
int drm_atomic_helper_check(struct drm_device *dev, |
struct drm_atomic_state *state); |
int drm_atomic_helper_commit(struct drm_device *dev, |
39,17 → 45,23 |
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, |
struct drm_atomic_state *old_state); |
void drm_atomic_helper_commit_pre_planes(struct drm_device *dev, |
void |
drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, |
struct drm_atomic_state *old_state); |
void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, |
struct drm_atomic_state *state); |
void drm_atomic_helper_commit_post_planes(struct drm_device *dev, |
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, |
struct drm_atomic_state *old_state); |
int drm_atomic_helper_prepare_planes(struct drm_device *dev, |
struct drm_atomic_state *state); |
void drm_atomic_helper_commit_planes(struct drm_device *dev, |
struct drm_atomic_state *state); |
struct drm_atomic_state *state, |
bool active_only); |
void drm_atomic_helper_cleanup_planes(struct drm_device *dev, |
struct drm_atomic_state *old_state); |
void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state); |
void drm_atomic_helper_swap_state(struct drm_device *dev, |
struct drm_atomic_state *state); |
63,7 → 75,11 |
uint32_t src_x, uint32_t src_y, |
uint32_t src_w, uint32_t src_h); |
int drm_atomic_helper_disable_plane(struct drm_plane *plane); |
int __drm_atomic_helper_disable_plane(struct drm_plane *plane, |
struct drm_plane_state *plane_state); |
int drm_atomic_helper_set_config(struct drm_mode_set *set); |
int __drm_atomic_helper_set_config(struct drm_mode_set *set, |
struct drm_atomic_state *state); |
int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, |
struct drm_property *property, |
78,23 → 94,42 |
struct drm_framebuffer *fb, |
struct drm_pending_vblank_event *event, |
uint32_t flags); |
int drm_atomic_helper_connector_dpms(struct drm_connector *connector, |
int mode); |
/* default implementations for state handling */ |
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); |
void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
struct drm_crtc_state * |
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); |
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
void drm_atomic_helper_plane_reset(struct drm_plane *plane); |
void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, |
struct drm_plane_state *state); |
struct drm_plane_state * |
drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); |
void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, |
struct drm_plane_state *state); |
void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, |
struct drm_plane_state *state); |
void drm_atomic_helper_connector_reset(struct drm_connector *connector); |
void |
__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, |
struct drm_connector_state *state); |
struct drm_connector_state * |
drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); |
struct drm_atomic_state * |
drm_atomic_helper_duplicate_state(struct drm_device *dev, |
struct drm_modeset_acquire_ctx *ctx); |
void |
__drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, |
struct drm_connector_state *state); |
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, |
struct drm_connector_state *state); |
123,4 → 158,41 |
#define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \ |
drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) |
/* |
* drm_atomic_plane_disabling - check whether a plane is being disabled |
* @plane: plane object |
* @old_state: previous atomic state |
* |
* Checks the atomic state of a plane to determine whether it's being disabled |
* or not. This also WARNs if it detects an invalid state (both CRTC and FB |
* need to either both be NULL or both be non-NULL). |
* |
* RETURNS: |
* True if the plane is being disabled, false otherwise. |
*/ |
static inline bool |
drm_atomic_plane_disabling(struct drm_plane *plane, |
struct drm_plane_state *old_state) |
{ |
/* |
* When disabling a plane, CRTC and FB should always be NULL together. |
* Anything else should be considered a bug in the atomic core, so we |
* gently warn about it. |
*/ |
WARN_ON((plane->state->crtc == NULL && plane->state->fb != NULL) || |
(plane->state->crtc != NULL && plane->state->fb == NULL)); |
/* |
* When using the transitional helpers, old_state may be NULL. If so, |
* we know nothing about the current state and have to assume that it |
* might be enabled. |
* |
* When using the atomic helpers, old_state won't be NULL. Therefore |
* this check assumes that either the driver will have reconstructed |
* the correct state in ->reset() or that the driver will have taken |
* appropriate measures to disable all planes. |
*/ |
return (!old_state || old_state->crtc) && !plane->state->crtc; |
} |
#endif /* DRM_ATOMIC_HELPER_H_ */ |
/drivers/include/drm/drm_crtc.h |
---|
31,6 → 31,7 |
#include <linux/idr.h> |
#include <linux/fb.h> |
#include <linux/hdmi.h> |
#include <linux/media-bus-format.h> |
#include <uapi/drm/drm_mode.h> |
#include <uapi/drm/drm_fourcc.h> |
#include <drm/drm_modeset_lock.h> |
52,7 → 53,6 |
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb |
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb |
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee |
#define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd |
#define DRM_MODE_OBJECT_ANY 0 |
struct drm_mode_object { |
63,8 → 63,16 |
#define DRM_OBJECT_MAX_PROPERTY 24 |
struct drm_object_properties { |
int count; |
uint32_t ids[DRM_OBJECT_MAX_PROPERTY]; |
int count, atomic_count; |
/* NOTE: if we ever start dynamically destroying properties (ie. |
* not at drm_mode_config_cleanup() time), then we'd have to do |
* a better job of detaching property from mode objects to avoid |
* dangling property pointers: |
*/ |
struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY]; |
/* do not read/write values directly, but use drm_object_property_get_value() |
* and drm_object_property_set_value(): |
*/ |
uint64_t values[DRM_OBJECT_MAX_PROPERTY]; |
}; |
78,10 → 86,12 |
} |
/* rotation property bits */ |
#define DRM_ROTATE_MASK 0x0f |
#define DRM_ROTATE_0 0 |
#define DRM_ROTATE_90 1 |
#define DRM_ROTATE_180 2 |
#define DRM_ROTATE_270 3 |
#define DRM_REFLECT_MASK (~DRM_ROTATE_MASK) |
#define DRM_REFLECT_X 4 |
#define DRM_REFLECT_Y 5 |
131,6 → 141,9 |
enum subpixel_order subpixel_order; |
u32 color_formats; |
const u32 *bus_formats; |
unsigned int num_bus_formats; |
/* Mask of supported hdmi deep color modes */ |
u8 edid_hdmi_dc_modes; |
190,6 → 203,7 |
const struct drm_framebuffer_funcs *funcs; |
unsigned int pitches[4]; |
unsigned int offsets[4]; |
uint64_t modifier[4]; |
unsigned int width; |
unsigned int height; |
/* depth can be 15 or 16 */ |
198,13 → 212,14 |
int flags; |
uint32_t pixel_format; /* fourcc format */ |
struct list_head filp_head; |
/* if you are using the helper */ |
void *helper_private; |
}; |
struct drm_property_blob { |
struct drm_mode_object base; |
struct list_head head; |
struct drm_device *dev; |
struct kref refcount; |
struct list_head head_global; |
struct list_head head_file; |
size_t length; |
unsigned char data[]; |
}; |
237,24 → 252,39 |
/** |
* struct drm_crtc_state - mutable CRTC state |
* @crtc: backpointer to the CRTC |
* @enable: whether the CRTC should be enabled, gates all other state |
* @mode_changed: for use by helpers and drivers when computing state updates |
* @active: whether the CRTC is actively displaying (used for DPMS) |
* @planes_changed: planes on this crtc are updated |
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed |
* @active_changed: crtc_state->active has been toggled. |
* @connectors_changed: connectors to this crtc have been updated |
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes |
* @last_vblank_count: for helpers and drivers to capture the vblank of the |
* update to ensure framebuffer cleanup isn't done too early |
* @planes_changed: for use by helpers and drivers when computing state updates |
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings |
* @mode: current mode timings |
* @event: optional pointer to a DRM event to signal upon completion of the |
* state update |
* @state: backpointer to global drm_atomic_state |
* |
* Note that the distinction between @enable and @active is rather subtile: |
* Flipping @active while @enable is set without changing anything else may |
* never return in a failure from the ->atomic_check callback. Userspace assumes |
* that a DPMS On will always succeed. In other words: @enable controls resource |
* assignment, @active controls the actual hardware state. |
*/ |
struct drm_crtc_state { |
struct drm_crtc *crtc; |
bool enable; |
bool active; |
/* computed state bits used by helpers and drivers */ |
bool planes_changed : 1; |
bool mode_changed : 1; |
bool active_changed : 1; |
bool connectors_changed : 1; |
/* attached planes bitmask: |
* WARNING: transitional helpers do not maintain plane_mask so |
271,6 → 301,9 |
struct drm_display_mode mode; |
/* blob property to expose current mode to atomic userspace */ |
struct drm_property_blob *mode_blob; |
struct drm_pending_vblank_event *event; |
struct drm_atomic_state *state; |
292,6 → 325,9 |
* @atomic_duplicate_state: duplicate the atomic state for this CRTC |
* @atomic_destroy_state: destroy an atomic state for this CRTC |
* @atomic_set_property: set a property on an atomic state for this CRTC |
* (do not call directly, use drm_atomic_crtc_set_property()) |
* @atomic_get_property: get a property on an atomic state for this CRTC |
* (do not call directly, use drm_atomic_crtc_get_property()) |
* |
* The drm_crtc_funcs structure is the central CRTC management structure |
* in the DRM. Each CRTC controls one or more connectors (note that the name |
351,6 → 387,10 |
struct drm_crtc_state *state, |
struct drm_property *property, |
uint64_t val); |
int (*atomic_get_property)(struct drm_crtc *crtc, |
const struct drm_crtc_state *state, |
struct drm_property *property, |
uint64_t *val); |
}; |
/** |
367,17 → 407,11 |
* @enabled: is this CRTC enabled? |
* @mode: current mode timings |
* @hwmode: mode timings as programmed to hw regs |
* @invert_dimensions: for purposes of error checking crtc vs fb sizes, |
* invert the width/height of the crtc. This is used if the driver |
* is performing 90 or 270 degree rotated scanout |
* @x: x position on screen |
* @y: y position on screen |
* @funcs: CRTC control functions |
* @gamma_size: size of gamma ramp |
* @gamma_store: gamma ramp values |
* @framedur_ns: precise frame timing |
* @linedur_ns: precise line timing |
* @pixeldur_ns: precise pixel timing |
* @helper_private: mid-layer private data |
* @properties: property tracking for this CRTC |
* @state: current atomic state for this CRTC |
421,8 → 455,6 |
*/ |
struct drm_display_mode hwmode; |
bool invert_dimensions; |
int x, y; |
const struct drm_crtc_funcs *funcs; |
430,11 → 462,8 |
uint32_t gamma_size; |
uint16_t *gamma_store; |
/* Constants needed for precise vblank and swap timestamping. */ |
int framedur_ns, linedur_ns, pixeldur_ns; |
/* if you are using the helper */ |
void *helper_private; |
const void *helper_private; |
struct drm_object_properties properties; |
449,11 → 478,14 |
/** |
* struct drm_connector_state - mutable connector state |
* @connector: backpointer to the connector |
* @crtc: CRTC to connect connector to, NULL if disabled |
* @best_encoder: can be used by helpers and drivers to select the encoder |
* @state: backpointer to global drm_atomic_state |
*/ |
struct drm_connector_state { |
struct drm_connector *connector; |
struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_connector() */ |
struct drm_encoder *best_encoder; |
463,7 → 495,7 |
/** |
* struct drm_connector_funcs - control connectors on a given device |
* @dpms: set power state (see drm_crtc_funcs above) |
* @dpms: set power state |
* @save: save connector state |
* @restore: restore connector state |
* @reset: reset connector after state has been invalidated (e.g. resume) |
475,6 → 507,9 |
* @atomic_duplicate_state: duplicate the atomic state for this connector |
* @atomic_destroy_state: destroy an atomic state for this connector |
* @atomic_set_property: set a property on an atomic state for this connector |
* (do not call directly, use drm_atomic_connector_set_property()) |
* @atomic_get_property: get a property on an atomic state for this connector |
* (do not call directly, use drm_atomic_connector_get_property()) |
* |
* Each CRTC may have one or more connectors attached to it. The functions |
* below allow the core DRM code to control connectors, enumerate available modes, |
481,7 → 516,7 |
* etc. |
*/ |
struct drm_connector_funcs { |
void (*dpms)(struct drm_connector *connector, int mode); |
int (*dpms)(struct drm_connector *connector, int mode); |
void (*save)(struct drm_connector *connector); |
void (*restore)(struct drm_connector *connector); |
void (*reset)(struct drm_connector *connector); |
508,6 → 543,10 |
struct drm_connector_state *state, |
struct drm_property *property, |
uint64_t val); |
int (*atomic_get_property)(struct drm_connector *connector, |
const struct drm_connector_state *state, |
struct drm_property *property, |
uint64_t *val); |
}; |
/** |
554,7 → 593,7 |
struct drm_crtc *crtc; |
struct drm_bridge *bridge; |
const struct drm_encoder_funcs *funcs; |
void *helper_private; |
const void *helper_private; |
}; |
/* should we poll this connector for connects and disconnects */ |
605,6 → 644,7 |
* @audio_latency: audio latency info from ELD, if found |
* @null_edid_counter: track sinks that give us all zeros for the EDID |
* @bad_edid_counter: track sinks that give us an EDID with invalid checksum |
* @edid_corrupt: indicates whether the last read EDID was corrupt |
* @debugfs_entry: debugfs directory for this connector |
* @state: current atomic state for this connector |
* @has_tile: is this connector connected to a tiled monitor |
658,7 → 698,7 |
/* requested DPMS state */ |
int dpms; |
void *helper_private; |
const void *helper_private; |
/* forced on connector */ |
struct drm_cmdline_mode cmdline_mode; |
677,6 → 717,11 |
int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */ |
unsigned bad_edid_counter; |
/* Flag for raw EDID header corruption - used in Displayport |
* compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6 |
*/ |
bool edid_corrupt; |
struct dentry *debugfs_entry; |
struct drm_connector_state *state; |
693,6 → 738,7 |
/** |
* struct drm_plane_state - mutable plane state |
* @plane: backpointer to the plane |
* @crtc: currently bound CRTC, NULL if disabled |
* @fb: currently bound framebuffer |
* @fence: optional fence to wait for before scanning out @fb |
709,6 → 755,8 |
* @state: backpointer to global drm_atomic_state |
*/ |
struct drm_plane_state { |
struct drm_plane *plane; |
struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */ |
struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */ |
struct fence *fence; |
721,6 → 769,9 |
uint32_t src_x, src_y; |
uint32_t src_h, src_w; |
/* Plane rotation */ |
unsigned int rotation; |
struct drm_atomic_state *state; |
}; |
735,6 → 786,9 |
* @atomic_duplicate_state: duplicate the atomic state for this plane |
* @atomic_destroy_state: destroy an atomic state for this plane |
* @atomic_set_property: set a property on an atomic state for this plane |
* (do not call directly, use drm_atomic_plane_set_property()) |
* @atomic_get_property: get a property on an atomic state for this plane |
* (do not call directly, use drm_atomic_plane_get_property()) |
*/ |
struct drm_plane_funcs { |
int (*update_plane)(struct drm_plane *plane, |
758,6 → 812,10 |
struct drm_plane_state *state, |
struct drm_property *property, |
uint64_t val); |
int (*atomic_get_property)(struct drm_plane *plane, |
const struct drm_plane_state *state, |
struct drm_property *property, |
uint64_t *val); |
}; |
enum drm_plane_type { |
774,6 → 832,7 |
* @possible_crtcs: pipes this plane can be bound to |
* @format_types: array of formats supported by this plane |
* @format_count: number of formats supported |
* @format_default: driver hasn't supplied supported formats for the plane |
* @crtc: currently bound CRTC |
* @fb: currently bound fb |
* @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by |
793,7 → 852,8 |
uint32_t possible_crtcs; |
uint32_t *format_types; |
uint32_t format_count; |
unsigned int format_count; |
bool format_default; |
struct drm_crtc *crtc; |
struct drm_framebuffer *fb; |
806,7 → 866,7 |
enum drm_plane_type type; |
void *helper_private; |
const void *helper_private; |
struct drm_plane_state *state; |
}; |
813,6 → 873,7 |
/** |
* struct drm_bridge_funcs - drm_bridge control functions |
* @attach: Called during drm_bridge_attach |
* @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge |
* @disable: Called right before encoder prepare, disables the bridge |
* @post_disable: Called right after encoder prepare, for lockstepped disable |
819,9 → 880,9 |
* @mode_set: Set this mode to the bridge |
* @pre_enable: Called right before encoder commit, for lockstepped commit |
* @enable: Called right after encoder commit, enables the bridge |
* @destroy: make object go away |
*/ |
struct drm_bridge_funcs { |
int (*attach)(struct drm_bridge *bridge); |
bool (*mode_fixup)(struct drm_bridge *bridge, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
832,31 → 893,36 |
struct drm_display_mode *adjusted_mode); |
void (*pre_enable)(struct drm_bridge *bridge); |
void (*enable)(struct drm_bridge *bridge); |
void (*destroy)(struct drm_bridge *bridge); |
}; |
/** |
* struct drm_bridge - central DRM bridge control structure |
* @dev: DRM device this bridge belongs to |
* @head: list management |
* @base: base mode object |
* @encoder: encoder to which this bridge is connected |
* @next: the next bridge in the encoder chain |
* @of_node: device node pointer to the bridge |
* @list: to keep track of all added bridges |
* @funcs: control functions |
* @driver_private: pointer to the bridge driver's internal context |
*/ |
struct drm_bridge { |
struct drm_device *dev; |
struct list_head head; |
struct drm_encoder *encoder; |
struct drm_bridge *next; |
#ifdef CONFIG_OF |
struct device_node *of_node; |
#endif |
struct list_head list; |
struct drm_mode_object base; |
const struct drm_bridge_funcs *funcs; |
void *driver_private; |
}; |
/** |
* struct struct drm_atomic_state - the global state object for atomic updates |
* struct drm_atomic_state - the global state object for atomic updates |
* @dev: parent DRM device |
* @flags: state flags like async update |
* @allow_modeset: allow full modeset |
* @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics |
* @planes: pointer to array of plane pointers |
* @plane_states: pointer to array of plane states pointers |
* @crtcs: pointer to array of CRTC pointers |
868,7 → 934,8 |
*/ |
struct drm_atomic_state { |
struct drm_device *dev; |
uint32_t flags; |
bool allow_modeset : 1; |
bool legacy_cursor_update : 1; |
struct drm_plane **planes; |
struct drm_plane_state **plane_states; |
struct drm_crtc **crtcs; |
912,9 → 979,12 |
* struct drm_mode_config_funcs - basic driver provided mode setting functions |
* @fb_create: create a new framebuffer object |
* @output_poll_changed: function to handle output configuration changes |
* @atomic_check: check whether a give atomic state update is possible |
* @atomic_check: check whether a given atomic state update is possible |
* @atomic_commit: commit an atomic state update previously verified with |
* atomic_check() |
* @atomic_state_alloc: allocate a new atomic state |
* @atomic_state_clear: clear the atomic state |
* @atomic_state_free: free the atomic state |
* |
* Some global (i.e. not per-CRTC, connector, etc) mode setting functions that |
* involve drivers. |
930,33 → 1000,12 |
int (*atomic_commit)(struct drm_device *dev, |
struct drm_atomic_state *a, |
bool async); |
struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev); |
void (*atomic_state_clear)(struct drm_atomic_state *state); |
void (*atomic_state_free)(struct drm_atomic_state *state); |
}; |
/** |
* struct drm_mode_group - group of mode setting resources for potential sub-grouping |
* @num_crtcs: CRTC count |
* @num_encoders: encoder count |
* @num_connectors: connector count |
* @num_bridges: bridge count |
* @id_list: list of KMS object IDs in this group |
* |
* Currently this simply tracks the global mode setting state. But in the |
* future it could allow groups of objects to be set aside into independent |
* control groups for use by different user level processes (e.g. two X servers |
* running simultaneously on different heads, each with their own mode |
* configuration and freedom of mode setting). |
*/ |
struct drm_mode_group { |
uint32_t num_crtcs; |
uint32_t num_encoders; |
uint32_t num_connectors; |
uint32_t num_bridges; |
/* list of object IDs for this group */ |
uint32_t *id_list; |
}; |
/** |
* struct drm_mode_config - Mode configuration control structure |
* @mutex: mutex protecting KMS related lists and structures |
* @connection_mutex: ww mutex protecting connector state and routing |
969,8 → 1018,6 |
* @fb_list: list of framebuffers available |
* @num_connector: number of connectors on this device |
* @connector_list: list of connector objects |
* @num_bridge: number of bridges on this device |
* @bridge_list: list of bridge objects |
* @num_encoder: number of encoders on this device |
* @encoder_list: list of encoder objects |
* @num_overlay_plane: number of overlay planes on this device |
989,6 → 1036,7 |
* @poll_running: track polling status for this device |
* @output_poll_work: delayed work for polling in process context |
* @property_blob_list: list of all the blob property objects |
* @blob_lock: mutex for blob property allocation and management |
* @*_property: core property tracking |
* @preferred_depth: preferred RBG pixel depth, used by fb helpers |
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering |
1015,8 → 1063,6 |
int num_connector; |
struct list_head connector_list; |
int num_bridge; |
struct list_head bridge_list; |
int num_encoder; |
struct list_head encoder_list; |
1043,8 → 1089,11 |
/* output poll support */ |
bool poll_enabled; |
bool poll_running; |
bool delayed_event; |
struct delayed_work output_poll_work; |
struct mutex blob_lock; |
/* pointers to standard properties */ |
struct list_head property_blob_list; |
struct drm_property *edid_property; |
1053,6 → 1102,18 |
struct drm_property *tile_property; |
struct drm_property *plane_type_property; |
struct drm_property *rotation_property; |
struct drm_property *prop_src_x; |
struct drm_property *prop_src_y; |
struct drm_property *prop_src_w; |
struct drm_property *prop_src_h; |
struct drm_property *prop_crtc_x; |
struct drm_property *prop_crtc_y; |
struct drm_property *prop_crtc_w; |
struct drm_property *prop_crtc_h; |
struct drm_property *prop_fb_id; |
struct drm_property *prop_crtc_id; |
struct drm_property *prop_active; |
struct drm_property *prop_mode_id; |
/* DVI-I properties */ |
struct drm_property *dvi_i_subconnector_property; |
1088,6 → 1149,9 |
/* whether async page flip is supported or not */ |
bool async_page_flip; |
/* whether the driver supports fb modifiers */ |
bool allow_fb_modifiers; |
/* cursor size */ |
uint32_t cursor_width, cursor_height; |
}; |
1153,10 → 1217,22 |
/* helper to unplug all connectors from sysfs for device */ |
extern void drm_connector_unplug_all(struct drm_device *dev); |
extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge, |
const struct drm_bridge_funcs *funcs); |
extern void drm_bridge_cleanup(struct drm_bridge *bridge); |
extern int drm_bridge_add(struct drm_bridge *bridge); |
extern void drm_bridge_remove(struct drm_bridge *bridge); |
extern struct drm_bridge *of_drm_find_bridge(struct device_node *np); |
extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); |
bool drm_bridge_mode_fixup(struct drm_bridge *bridge, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
void drm_bridge_disable(struct drm_bridge *bridge); |
void drm_bridge_post_disable(struct drm_bridge *bridge); |
void drm_bridge_mode_set(struct drm_bridge *bridge, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
void drm_bridge_pre_enable(struct drm_bridge *bridge); |
void drm_bridge_enable(struct drm_bridge *bridge); |
extern int drm_encoder_init(struct drm_device *dev, |
struct drm_encoder *encoder, |
const struct drm_encoder_funcs *funcs, |
1180,17 → 1256,22 |
unsigned long possible_crtcs, |
const struct drm_plane_funcs *funcs, |
const uint32_t *formats, |
uint32_t format_count, |
unsigned int format_count, |
enum drm_plane_type type); |
extern int drm_plane_init(struct drm_device *dev, |
struct drm_plane *plane, |
unsigned long possible_crtcs, |
const struct drm_plane_funcs *funcs, |
const uint32_t *formats, uint32_t format_count, |
const uint32_t *formats, unsigned int format_count, |
bool is_primary); |
extern void drm_plane_cleanup(struct drm_plane *plane); |
extern unsigned int drm_plane_index(struct drm_plane *plane); |
extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); |
extern void drm_plane_force_disable(struct drm_plane *plane); |
extern int drm_plane_check_pixel_format(const struct drm_plane *plane, |
u32 format); |
extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode, |
int *hdisplay, int *vdisplay); |
extern int drm_crtc_check_viewport(const struct drm_crtc *crtc, |
int x, int y, |
const struct drm_display_mode *mode, |
1206,9 → 1287,8 |
extern const char *drm_get_tv_subconnector_name(int val); |
extern const char *drm_get_tv_select_name(int val); |
extern void drm_fb_release(struct drm_file *file_priv); |
extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); |
extern void drm_mode_group_destroy(struct drm_mode_group *group); |
extern void drm_reinit_primary_mode_group(struct drm_device *dev); |
extern void drm_property_destroy_user_blobs(struct drm_device *dev, |
struct drm_file *file_priv); |
extern bool drm_probe_ddc(struct i2c_adapter *adapter); |
extern struct edid *drm_get_edid(struct drm_connector *connector, |
struct i2c_adapter *adapter); |
1224,6 → 1304,10 |
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, |
const struct edid *edid); |
extern int drm_display_info_set_bus_formats(struct drm_display_info *info, |
const u32 *formats, |
unsigned int num_formats); |
static inline bool drm_property_type_is(struct drm_property *property, |
uint32_t type) |
{ |
1279,6 → 1363,15 |
int64_t min, int64_t max); |
struct drm_property *drm_property_create_object(struct drm_device *dev, |
int flags, const char *name, uint32_t type); |
struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, |
const char *name); |
struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, |
size_t length, |
const void *data); |
struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, |
uint32_t id); |
struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob); |
void drm_property_unreference_blob(struct drm_property_blob *blob); |
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); |
extern int drm_property_add_enum(struct drm_property *property, int index, |
uint64_t value, const char *name); |
1285,11 → 1378,15 |
extern int drm_mode_create_dvi_i_properties(struct drm_device *dev); |
extern int drm_mode_create_tv_properties(struct drm_device *dev, |
unsigned int num_modes, |
char *modes[]); |
const char * const modes[]); |
extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); |
extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev); |
extern int drm_mode_create_dirty_info_property(struct drm_device *dev); |
extern int drm_mode_create_suggested_offset_properties(struct drm_device *dev); |
extern bool drm_property_change_valid_get(struct drm_property *property, |
uint64_t value, struct drm_mode_object **ref); |
extern void drm_property_change_valid_put(struct drm_property *property, |
struct drm_mode_object *ref); |
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, |
struct drm_encoder *encoder); |
1334,6 → 1431,10 |
void *data, struct drm_file *file_priv); |
extern int drm_mode_getblob_ioctl(struct drm_device *dev, |
void *data, struct drm_file *file_priv); |
extern int drm_mode_createblob_ioctl(struct drm_device *dev, |
void *data, struct drm_file *file_priv); |
extern int drm_mode_destroyblob_ioctl(struct drm_device *dev, |
void *data, struct drm_file *file_priv); |
extern int drm_mode_connector_property_set_ioctl(struct drm_device *dev, |
void *data, struct drm_file *file_priv); |
extern int drm_mode_getencoder(struct drm_device *dev, |
1355,7 → 1456,8 |
int hpref, int vpref); |
extern int drm_edid_header_is_valid(const u8 *raw_edid); |
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid); |
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid, |
bool *edid_corrupt); |
extern bool drm_edid_is_valid(struct edid *edid); |
extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, |
1381,6 → 1483,8 |
extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, |
struct drm_property *property, |
uint64_t value); |
extern int drm_mode_atomic_ioctl(struct drm_device *dev, |
void *data, struct drm_file *file_priv); |
extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, |
int *bpp); |
1436,17 → 1540,46 |
return mo ? obj_to_property(mo) : NULL; |
} |
static inline struct drm_property_blob * |
drm_property_blob_find(struct drm_device *dev, uint32_t id) |
/* Plane list iterator for legacy (overlay only) planes. */ |
#define drm_for_each_legacy_plane(plane, dev) \ |
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \ |
if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
#define drm_for_each_plane(plane, dev) \ |
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) |
#define drm_for_each_crtc(crtc, dev) \ |
list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) |
static inline void |
assert_drm_connector_list_read_locked(struct drm_mode_config *mode_config) |
{ |
struct drm_mode_object *mo; |
mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB); |
return mo ? obj_to_blob(mo) : NULL; |
/* |
* The connector hotadd/remove code currently grabs both locks when |
* updating lists. Hence readers need only hold either of them to be |
* safe and the check amounts to |
* |
* WARN_ON(not_holding(A) && not_holding(B)). |
*/ |
WARN_ON(!mutex_is_locked(&mode_config->mutex) && |
!drm_modeset_is_locked(&mode_config->connection_mutex)); |
} |
/* Plane list iterator for legacy (overlay only) planes. */ |
#define drm_for_each_legacy_plane(plane, planelist) \ |
list_for_each_entry(plane, planelist, head) \ |
if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
#define drm_for_each_connector(connector, dev) \ |
for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \ |
connector = list_first_entry(&(dev)->mode_config.connector_list, \ |
struct drm_connector, head); \ |
&connector->head != (&(dev)->mode_config.connector_list); \ |
connector = list_next_entry(connector, head)) |
#define drm_for_each_encoder(encoder, dev) \ |
list_for_each_entry(encoder, &(dev)->mode_config.encoder_list, head) |
#define drm_for_each_fb(fb, dev) \ |
for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ |
fb = list_first_entry(&(dev)->mode_config.fb_list, \ |
struct drm_framebuffer, head); \ |
&fb->head != (&(dev)->mode_config.fb_list); \ |
fb = list_next_entry(fb, head)) |
#endif /* __DRM_CRTC_H__ */ |
/drivers/include/drm/drm_crtc_helper.h |
---|
39,6 → 39,8 |
#include <linux/fb.h> |
#include <drm/drm_crtc.h> |
enum mode_set_atomic { |
LEAVE_ATOMIC_MODE_SET, |
ENTER_ATOMIC_MODE_SET, |
45,11 → 47,30 |
}; |
/** |
* drm_crtc_helper_funcs - helper operations for CRTCs |
* @mode_fixup: try to fixup proposed mode for this connector |
* struct drm_crtc_helper_funcs - helper operations for CRTCs |
* @dpms: set power state |
* @prepare: prepare the CRTC, called before @mode_set |
* @commit: commit changes to CRTC, called after @mode_set |
* @mode_fixup: try to fixup proposed mode for this CRTC |
* @mode_set: set this mode |
* @mode_set_nofb: set mode only (no scanout buffer attached) |
* @mode_set_base: update the scanout buffer |
* @mode_set_base_atomic: non-blocking mode set (used for kgdb support) |
* @load_lut: load color palette |
* @disable: disable CRTC when no longer in use |
* @enable: enable CRTC |
* @atomic_check: check for validity of an atomic state |
* @atomic_begin: begin atomic update |
* @atomic_flush: flush atomic update |
* |
* The helper operations are called by the mid-layer CRTC helper. |
* |
* Note that with atomic helpers @dpms, @prepare and @commit hooks are |
* deprecated. Used @enable and @disable instead exclusively. |
* |
* With legacy crtc helpers there's a big semantic difference between @disable |
* and the other hooks: @disable also needs to release any resources acquired in |
* @mode_set (like shared PLLs). |
*/ |
struct drm_crtc_helper_funcs { |
/* |
68,6 → 89,7 |
int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode, int x, int y, |
struct drm_framebuffer *old_fb); |
/* Actually set the mode for atomic helpers, optional */ |
void (*mode_set_nofb)(struct drm_crtc *crtc); |
/* Move the crtc on the current fb to the given position *optional* */ |
80,22 → 102,41 |
/* reload the current crtc LUT */ |
void (*load_lut)(struct drm_crtc *crtc); |
/* disable crtc when not in use - more explicit than dpms off */ |
void (*disable)(struct drm_crtc *crtc); |
void (*enable)(struct drm_crtc *crtc); |
/* atomic helpers */ |
int (*atomic_check)(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
void (*atomic_begin)(struct drm_crtc *crtc); |
void (*atomic_flush)(struct drm_crtc *crtc); |
void (*atomic_begin)(struct drm_crtc *crtc, |
struct drm_crtc_state *old_crtc_state); |
void (*atomic_flush)(struct drm_crtc *crtc, |
struct drm_crtc_state *old_crtc_state); |
}; |
/** |
* drm_encoder_helper_funcs - helper operations for encoders |
* struct drm_encoder_helper_funcs - helper operations for encoders |
* @dpms: set power state |
* @save: save connector state |
* @restore: restore connector state |
* @mode_fixup: try to fixup proposed mode for this connector |
* @mode_set: set this mode |
* @prepare: part of the disable sequence, called before the CRTC modeset |
* @commit: called after the CRTC modeset |
* @mode_set: set this mode, optional for atomic helpers |
* @get_crtc: return CRTC that the encoder is currently attached to |
* @detect: connection status detection |
* @disable: disable encoder when not in use (overrides DPMS off) |
* @enable: enable encoder |
* @atomic_check: check for validity of an atomic update |
* |
* The helper operations are called by the mid-layer CRTC helper. |
* |
* Note that with atomic helpers @dpms, @prepare and @commit hooks are |
* deprecated. Used @enable and @disable instead exclusively. |
* |
* With legacy crtc helpers there's a big semantic difference between @disable |
* and the other hooks: @disable also needs to release any resources acquired in |
* @mode_set (like shared PLLs). |
*/ |
struct drm_encoder_helper_funcs { |
void (*dpms)(struct drm_encoder *encoder, int mode); |
114,14 → 155,22 |
/* detect for DAC style encoders */ |
enum drm_connector_status (*detect)(struct drm_encoder *encoder, |
struct drm_connector *connector); |
/* disable encoder when not in use - more explicit than dpms off */ |
void (*disable)(struct drm_encoder *encoder); |
void (*enable)(struct drm_encoder *encoder); |
/* atomic helpers */ |
int (*atomic_check)(struct drm_encoder *encoder, |
struct drm_crtc_state *crtc_state, |
struct drm_connector_state *conn_state); |
}; |
/** |
* drm_connector_helper_funcs - helper operations for connectors |
* struct drm_connector_helper_funcs - helper operations for connectors |
* @get_modes: get mode list for this connector |
* @mode_valid (optional): is this mode valid on the given connector? |
* @mode_valid: is this mode valid on the given connector? (optional) |
* @best_encoder: return the preferred encoder for this connector |
* @atomic_best_encoder: atomic version of @best_encoder |
* |
* The helper operations are called by the mid-layer CRTC helper. |
*/ |
130,6 → 179,8 |
enum drm_mode_status (*mode_valid)(struct drm_connector *connector, |
struct drm_display_mode *mode); |
struct drm_encoder *(*best_encoder)(struct drm_connector *connector); |
struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, |
struct drm_connector_state *connector_state); |
}; |
extern void drm_helper_disable_unused_functions(struct drm_device *dev); |
141,7 → 192,7 |
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); |
extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); |
extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode); |
extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode); |
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *); |
151,19 → 202,19 |
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, |
const struct drm_crtc_helper_funcs *funcs) |
{ |
crtc->helper_private = (void *)funcs; |
crtc->helper_private = funcs; |
} |
static inline void drm_encoder_helper_add(struct drm_encoder *encoder, |
const struct drm_encoder_helper_funcs *funcs) |
{ |
encoder->helper_private = (void *)funcs; |
encoder->helper_private = funcs; |
} |
static inline void drm_connector_helper_add(struct drm_connector *connector, |
const struct drm_connector_helper_funcs *funcs) |
{ |
connector->helper_private = (void *)funcs; |
connector->helper_private = funcs; |
} |
extern void drm_helper_resume_force_mode(struct drm_device *dev); |
189,5 → 240,6 |
extern void drm_kms_helper_poll_disable(struct drm_device *dev); |
extern void drm_kms_helper_poll_enable(struct drm_device *dev); |
extern void drm_kms_helper_poll_enable_locked(struct drm_device *dev); |
#endif |
/drivers/include/drm/drm_dp_helper.h |
---|
42,9 → 42,11 |
* 1.2 formally includes both eDP and DPI definitions. |
*/ |
#define DP_AUX_MAX_PAYLOAD_BYTES 16 |
#define DP_AUX_I2C_WRITE 0x0 |
#define DP_AUX_I2C_READ 0x1 |
#define DP_AUX_I2C_STATUS 0x2 |
#define DP_AUX_I2C_WRITE_STATUS_UPDATE 0x2 |
#define DP_AUX_I2C_MOT 0x4 |
#define DP_AUX_NATIVE_WRITE 0x8 |
#define DP_AUX_NATIVE_READ 0x9 |
92,6 → 94,15 |
# define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */ |
# define DP_OUI_SUPPORT (1 << 7) |
#define DP_RECEIVE_PORT_0_CAP_0 0x008 |
# define DP_LOCAL_EDID_PRESENT (1 << 1) |
# define DP_ASSOCIATED_TO_PRECEDING_PORT (1 << 2) |
#define DP_RECEIVE_PORT_0_BUFFER_SIZE 0x009 |
#define DP_RECEIVE_PORT_1_CAP_0 0x00a |
#define DP_RECEIVE_PORT_1_BUFFER_SIZE 0x00b |
#define DP_I2C_SPEED_CAP 0x00c /* DPI */ |
# define DP_I2C_SPEED_1K 0x01 |
# define DP_I2C_SPEED_5K 0x02 |
101,8 → 112,19 |
# define DP_I2C_SPEED_1M 0x20 |
#define DP_EDP_CONFIGURATION_CAP 0x00d /* XXX 1.2? */ |
# define DP_ALTERNATE_SCRAMBLER_RESET_CAP (1 << 0) |
# define DP_FRAMING_CHANGE_CAP (1 << 1) |
# define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */ |
#define DP_TRAINING_AUX_RD_INTERVAL 0x00e /* XXX 1.2? */ |
#define DP_ADAPTER_CAP 0x00f /* 1.2 */ |
# define DP_FORCE_LOAD_SENSE_CAP (1 << 0) |
# define DP_ALTERNATE_I2C_PATTERN_CAP (1 << 1) |
#define DP_SUPPORTED_LINK_RATES 0x010 /* eDP 1.4 */ |
# define DP_MAX_SUPPORTED_RATES 8 /* 16-bit little-endian */ |
/* Multiple stream transport */ |
#define DP_FAUX_CAP 0x020 /* 1.2 */ |
# define DP_FAUX_CAP_1 (1 << 0) |
110,10 → 132,56 |
#define DP_MSTM_CAP 0x021 /* 1.2 */ |
# define DP_MST_CAP (1 << 0) |
#define DP_NUMBER_OF_AUDIO_ENDPOINTS 0x022 /* 1.2 */ |
/* AV_SYNC_DATA_BLOCK 1.2 */ |
#define DP_AV_GRANULARITY 0x023 |
# define DP_AG_FACTOR_MASK (0xf << 0) |
# define DP_AG_FACTOR_3MS (0 << 0) |
# define DP_AG_FACTOR_2MS (1 << 0) |
# define DP_AG_FACTOR_1MS (2 << 0) |
# define DP_AG_FACTOR_500US (3 << 0) |
# define DP_AG_FACTOR_200US (4 << 0) |
# define DP_AG_FACTOR_100US (5 << 0) |
# define DP_AG_FACTOR_10US (6 << 0) |
# define DP_AG_FACTOR_1US (7 << 0) |
# define DP_VG_FACTOR_MASK (0xf << 4) |
# define DP_VG_FACTOR_3MS (0 << 4) |
# define DP_VG_FACTOR_2MS (1 << 4) |
# define DP_VG_FACTOR_1MS (2 << 4) |
# define DP_VG_FACTOR_500US (3 << 4) |
# define DP_VG_FACTOR_200US (4 << 4) |
# define DP_VG_FACTOR_100US (5 << 4) |
#define DP_AUD_DEC_LAT0 0x024 |
#define DP_AUD_DEC_LAT1 0x025 |
#define DP_AUD_PP_LAT0 0x026 |
#define DP_AUD_PP_LAT1 0x027 |
#define DP_VID_INTER_LAT 0x028 |
#define DP_VID_PROG_LAT 0x029 |
#define DP_REP_LAT 0x02a |
#define DP_AUD_DEL_INS0 0x02b |
#define DP_AUD_DEL_INS1 0x02c |
#define DP_AUD_DEL_INS2 0x02d |
/* End of AV_SYNC_DATA_BLOCK */ |
#define DP_RECEIVER_ALPM_CAP 0x02e /* eDP 1.4 */ |
# define DP_ALPM_CAP (1 << 0) |
#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP 0x02f /* eDP 1.4 */ |
# define DP_AUX_FRAME_SYNC_CAP (1 << 0) |
#define DP_GUID 0x030 /* 1.2 */ |
#define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */ |
# define DP_PSR_IS_SUPPORTED 1 |
# define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */ |
#define DP_PSR_CAPS 0x071 /* XXX 1.2? */ |
# define DP_PSR_NO_TRAIN_ON_EXIT 1 |
# define DP_PSR_SETUP_TIME_330 (0 << 1) |
153,6 → 221,7 |
/* link configuration */ |
#define DP_LINK_BW_SET 0x100 |
# define DP_LINK_RATE_TABLE 0x00 /* eDP 1.4 */ |
# define DP_LINK_BW_1_62 0x06 |
# define DP_LINK_BW_2_7 0x0a |
# define DP_LINK_BW_5_4 0x14 /* 1.2 */ |
168,11 → 237,12 |
# define DP_TRAINING_PATTERN_3 3 /* 1.2 */ |
# define DP_TRAINING_PATTERN_MASK 0x3 |
# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) |
# define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) |
# define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) |
# define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) |
# define DP_LINK_QUAL_PATTERN_MASK (3 << 2) |
/* DPCD 1.1 only. For DPCD >= 1.2 see per-lane DP_LINK_QUAL_LANEn_SET */ |
# define DP_LINK_QUAL_PATTERN_11_DISABLE (0 << 2) |
# define DP_LINK_QUAL_PATTERN_11_D10_2 (1 << 2) |
# define DP_LINK_QUAL_PATTERN_11_ERROR_RATE (2 << 2) |
# define DP_LINK_QUAL_PATTERN_11_PRBS7 (3 << 2) |
# define DP_LINK_QUAL_PATTERN_11_MASK (3 << 2) |
# define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) |
# define DP_LINK_SCRAMBLING_DISABLE (1 << 5) |
215,17 → 285,63 |
/* bitmask as for DP_I2C_SPEED_CAP */ |
#define DP_EDP_CONFIGURATION_SET 0x10a /* XXX 1.2? */ |
# define DP_ALTERNATE_SCRAMBLER_RESET_ENABLE (1 << 0) |
# define DP_FRAMING_CHANGE_ENABLE (1 << 1) |
# define DP_PANEL_SELF_TEST_ENABLE (1 << 7) |
#define DP_LINK_QUAL_LANE0_SET 0x10b /* DPCD >= 1.2 */ |
#define DP_LINK_QUAL_LANE1_SET 0x10c |
#define DP_LINK_QUAL_LANE2_SET 0x10d |
#define DP_LINK_QUAL_LANE3_SET 0x10e |
# define DP_LINK_QUAL_PATTERN_DISABLE 0 |
# define DP_LINK_QUAL_PATTERN_D10_2 1 |
# define DP_LINK_QUAL_PATTERN_ERROR_RATE 2 |
# define DP_LINK_QUAL_PATTERN_PRBS7 3 |
# define DP_LINK_QUAL_PATTERN_80BIT_CUSTOM 4 |
# define DP_LINK_QUAL_PATTERN_HBR2_EYE 5 |
# define DP_LINK_QUAL_PATTERN_MASK 7 |
#define DP_TRAINING_LANE0_1_SET2 0x10f |
#define DP_TRAINING_LANE2_3_SET2 0x110 |
# define DP_LANE02_POST_CURSOR2_SET_MASK (3 << 0) |
# define DP_LANE02_MAX_POST_CURSOR2_REACHED (1 << 2) |
# define DP_LANE13_POST_CURSOR2_SET_MASK (3 << 4) |
# define DP_LANE13_MAX_POST_CURSOR2_REACHED (1 << 6) |
#define DP_MSTM_CTRL 0x111 /* 1.2 */ |
# define DP_MST_EN (1 << 0) |
# define DP_UP_REQ_EN (1 << 1) |
# define DP_UPSTREAM_IS_SRC (1 << 2) |
#define DP_AUDIO_DELAY0 0x112 /* 1.2 */ |
#define DP_AUDIO_DELAY1 0x113 |
#define DP_AUDIO_DELAY2 0x114 |
#define DP_LINK_RATE_SET 0x115 /* eDP 1.4 */ |
# define DP_LINK_RATE_SET_SHIFT 0 |
# define DP_LINK_RATE_SET_MASK (7 << 0) |
#define DP_RECEIVER_ALPM_CONFIG 0x116 /* eDP 1.4 */ |
# define DP_ALPM_ENABLE (1 << 0) |
# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1) |
#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF 0x117 /* eDP 1.4 */ |
# define DP_AUX_FRAME_SYNC_ENABLE (1 << 0) |
# define DP_IRQ_HPD_ENABLE (1 << 1) |
#define DP_UPSTREAM_DEVICE_DP_PWR_NEED 0x118 /* 1.2 */ |
# define DP_PWR_NOT_NEEDED (1 << 0) |
#define DP_AUX_FRAME_SYNC_VALUE 0x15c /* eDP 1.4 */ |
# define DP_AUX_FRAME_SYNC_VALID (1 << 0) |
#define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ |
# define DP_PSR_ENABLE (1 << 0) |
# define DP_PSR_MAIN_LINK_ACTIVE (1 << 1) |
# define DP_PSR_CRC_VERIFICATION (1 << 2) |
# define DP_PSR_FRAME_CAPTURE (1 << 3) |
# define DP_PSR_SELECTIVE_UPDATE (1 << 4) |
# define DP_PSR_IRQ_HPD_WITH_CRC_ERRORS (1 << 5) |
#define DP_ADAPTER_CTRL 0x1a0 |
# define DP_ADAPTER_CTRL_FORCE_LOAD_SENSE (1 << 0) |
304,7 → 420,7 |
#define DP_TEST_SINK_MISC 0x246 |
# define DP_TEST_CRC_SUPPORTED (1 << 5) |
# define DP_TEST_COUNT_MASK 0x7 |
# define DP_TEST_COUNT_MASK 0xf |
#define DP_TEST_RESPONSE 0x260 |
# define DP_TEST_ACK (1 << 0) |
332,6 → 448,49 |
# define DP_SET_POWER_D3 0x2 |
# define DP_SET_POWER_MASK 0x3 |
#define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ |
# define DP_EDP_11 0x00 |
# define DP_EDP_12 0x01 |
# define DP_EDP_13 0x02 |
# define DP_EDP_14 0x03 |
#define DP_EDP_GENERAL_CAP_1 0x701 |
#define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP 0x702 |
#define DP_EDP_GENERAL_CAP_2 0x703 |
#define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */ |
#define DP_EDP_DISPLAY_CONTROL_REGISTER 0x720 |
#define DP_EDP_BACKLIGHT_MODE_SET_REGISTER 0x721 |
#define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722 |
#define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723 |
#define DP_EDP_PWMGEN_BIT_COUNT 0x724 |
#define DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN 0x725 |
#define DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX 0x726 |
#define DP_EDP_BACKLIGHT_CONTROL_STATUS 0x727 |
#define DP_EDP_BACKLIGHT_FREQ_SET 0x728 |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MSB 0x72a |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_MID 0x72b |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MIN_LSB 0x72c |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MSB 0x72d |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_MID 0x72e |
#define DP_EDP_BACKLIGHT_FREQ_CAP_MAX_LSB 0x72f |
#define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732 |
#define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733 |
#define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */ |
#define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */ |
#define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ |
#define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ |
#define DP_SIDEBAND_MSG_DOWN_REP_BASE 0x1400 /* 1.2 MST */ |
350,6 → 509,7 |
#define DP_PSR_ERROR_STATUS 0x2006 /* XXX 1.2? */ |
# define DP_PSR_LINK_CRC_ERROR (1 << 0) |
# define DP_PSR_RFB_STORAGE_ERROR (1 << 1) |
# define DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR (1 << 2) /* eDP 1.4 */ |
#define DP_PSR_ESI 0x2007 /* XXX 1.2? */ |
# define DP_PSR_CAPS_CHANGE (1 << 0) |
363,6 → 523,9 |
# define DP_PSR_SINK_INTERNAL_ERROR 7 |
# define DP_PSR_SINK_STATE_MASK 0x07 |
#define DP_RECEIVER_ALPM_STATUS 0x200b /* eDP 1.4 */ |
# define DP_ALPM_LOCK_TIMEOUT_ERROR (1 << 0) |
/* DP 1.2 Sideband message defines */ |
/* peer device type - DP 1.2a Table 2-92 */ |
#define DP_PEER_DEVICE_NONE 0x0 |
405,6 → 568,10 |
#define MODE_I2C_READ 4 |
#define MODE_I2C_STOP 8 |
/* DP 1.2 MST PORTs - Section 2.5.1 v1.2a spec */ |
#define DP_MST_PHYSICAL_PORT_0 0 |
#define DP_MST_LOGICAL_PORT_0 8 |
#define DP_LINK_STATUS_SIZE 6 |
bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], |
int lane_count); |
415,6 → 582,7 |
u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE], |
int lane); |
#define DP_BRANCH_OUI_HEADER_SIZE 0xc |
#define DP_RECEIVER_CAP_SIZE 0xf |
#define EDP_PSR_RECEIVER_CAP_SIZE 2 |
470,6 → 638,13 |
(dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP); |
} |
static inline bool |
drm_dp_tps3_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) |
{ |
return dpcd[DP_DPCD_REV] >= 0x12 && |
dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED; |
} |
/* |
* DisplayPort AUX channel |
*/ |
516,9 → 691,12 |
* An AUX channel can also be used to transport I2C messages to a sink. A |
* typical application of that is to access an EDID that's present in the |
* sink device. The .transfer() function can also be used to execute such |
* transactions. The drm_dp_aux_register_i2c_bus() function registers an |
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers |
* should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter. |
* transactions. The drm_dp_aux_register() function registers an I2C |
* adapter that can be passed to drm_probe_ddc(). Upon removal, drivers |
* should call drm_dp_aux_unregister() to remove the I2C adapter. |
* The I2C adapter uses long transfers by default; if a partial response is |
* received, the adapter will drop down to the size given by the partial |
* response for this transaction only. |
* |
* Note that the aux helper code assumes that the .transfer() function |
* only modifies the reply field of the drm_dp_aux_msg structure. The |
586,6 → 764,7 |
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); |
int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); |
int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); |
int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); |
int drm_dp_aux_register(struct drm_dp_aux *aux); |
/drivers/include/drm/drm_dp_mst_helper.h |
---|
253,6 → 253,7 |
u8 *bytes; |
}; |
#define DP_REMOTE_I2C_READ_MAX_TRANSACTIONS 4 |
struct drm_dp_remote_i2c_read { |
u8 num_transactions; |
u8 port_number; |
262,7 → 263,7 |
u8 *bytes; |
u8 no_stop_bit; |
u8 i2c_transaction_delay; |
} transactions[4]; |
} transactions[DP_REMOTE_I2C_READ_MAX_TRANSACTIONS]; |
u8 read_i2c_device_id; |
u8 num_bytes_read; |
}; |
374,6 → 375,7 |
struct drm_dp_mst_topology_cbs { |
/* create a connector for a port */ |
struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path); |
void (*register_connector)(struct drm_connector *connector); |
void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr, |
struct drm_connector *connector); |
void (*hotplug)(struct drm_dp_mst_topology_mgr *mgr); |
463,6 → 465,10 |
struct work_struct work; |
struct work_struct tx_work; |
struct list_head destroy_connector_list; |
struct mutex destroy_connector_lock; |
struct work_struct destroy_connector_work; |
}; |
int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, struct device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id); |
486,7 → 492,9 |
bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots); |
int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); |
void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); |
/drivers/include/drm/drm_edid.h |
---|
215,6 → 215,8 |
#define DRM_ELD_VER 0 |
# define DRM_ELD_VER_SHIFT 3 |
# define DRM_ELD_VER_MASK (0x1f << 3) |
# define DRM_ELD_VER_CEA861D (2 << 3) /* supports 861D or below */ |
# define DRM_ELD_VER_CANNED (0x1f << 3) |
#define DRM_ELD_BASELINE_ELD_LEN 2 /* in dwords! */ |
324,9 → 326,8 |
int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); |
int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb); |
int drm_av_sync_delay(struct drm_connector *connector, |
struct drm_display_mode *mode); |
struct drm_connector *drm_select_eld(struct drm_encoder *encoder, |
struct drm_display_mode *mode); |
const struct drm_display_mode *mode); |
struct drm_connector *drm_select_eld(struct drm_encoder *encoder); |
int drm_load_edid_firmware(struct drm_connector *connector); |
int |
346,6 → 347,25 |
} |
/** |
* drm_eld_sad - Get ELD SAD structures. |
* @eld: pointer to an eld memory structure with sad_count set |
*/ |
static inline const uint8_t *drm_eld_sad(const uint8_t *eld) |
{ |
unsigned int ver, mnl; |
ver = (eld[DRM_ELD_VER] & DRM_ELD_VER_MASK) >> DRM_ELD_VER_SHIFT; |
if (ver != 2 && ver != 31) |
return NULL; |
mnl = drm_eld_mnl(eld); |
if (mnl > 16) |
return NULL; |
return eld + DRM_ELD_CEA_SAD(mnl, 0); |
} |
/** |
* drm_eld_sad_count - Get ELD SAD count. |
* @eld: pointer to an eld memory structure with sad_count set |
*/ |
/drivers/include/drm/drm_fb_helper.h |
---|
44,6 → 44,25 |
int x, y; |
}; |
/** |
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size |
* @fb_width: fbdev width |
* @fb_height: fbdev height |
* @surface_width: scanout buffer width |
* @surface_height: scanout buffer height |
* @surface_bpp: scanout buffer bpp |
* @surface_depth: scanout buffer depth |
* |
* Note that the scanout surface width/height may be larger than the fbdev |
* width/height. In case of multiple displays, the scanout surface is sized |
* according to the largest width/height (so it is large enough for all CRTCs |
* to scanout). But the fbdev width/height is sized to the minimum width/ |
* height of all the displays. This ensures that fbcon fits on the smallest |
* of the attached displays. |
* |
* So what is passed to drm_fb_helper_fill_var() should be fb_width/fb_height, |
* rather than the surface size. |
*/ |
struct drm_fb_helper_surface_size { |
u32 fb_width; |
u32 fb_height; |
85,6 → 104,20 |
struct drm_connector *connector; |
}; |
/** |
* struct drm_fb_helper - helper to emulate fbdev on top of kms |
* @fb: Scanout framebuffer object |
* @dev: DRM device |
* @crtc_count: number of possible CRTCs |
* @crtc_info: per-CRTC helper state (mode, x/y offset, etc) |
* @connector_count: number of connected connectors |
* @connector_info_alloc_count: size of connector_info |
* @funcs: driver callbacks for fb helper |
* @fbdev: emulated fbdev device info struct |
* @pseudo_palette: fake palette of 16 colors |
* @kernel_fb_list: list_head in kernel_fb_helper_list |
* @delayed_hotplug: was there a hotplug while kms master active? |
*/ |
struct drm_fb_helper { |
struct drm_framebuffer *fb; |
struct drm_device *dev; |
101,8 → 134,20 |
/* we got a hotplug but fbdev wasn't running the console |
delay until next set_par */ |
bool delayed_hotplug; |
/** |
* @atomic: |
* |
* Use atomic updates for restore_fbdev_mode(), etc. This defaults to |
* true if driver has DRIVER_ATOMIC feature flag, but drivers can |
* override it to true after drm_fb_helper_init() if they support atomic |
* modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper |
* does not require ASYNC commits). |
*/ |
bool atomic; |
}; |
#ifdef CONFIG_DRM_FBDEV_EMULATION |
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, |
const struct drm_fb_helper_funcs *funcs); |
int drm_fb_helper_init(struct drm_device *dev, |
116,16 → 161,43 |
int drm_fb_helper_check_var(struct fb_var_screeninfo *var, |
struct fb_info *info); |
bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); |
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); |
struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper); |
void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); |
void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper); |
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, |
uint32_t fb_width, uint32_t fb_height); |
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, |
uint32_t depth); |
void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper); |
ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, |
size_t count, loff_t *ppos); |
ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, |
size_t count, loff_t *ppos); |
void drm_fb_helper_sys_fillrect(struct fb_info *info, |
const struct fb_fillrect *rect); |
void drm_fb_helper_sys_copyarea(struct fb_info *info, |
const struct fb_copyarea *area); |
void drm_fb_helper_sys_imageblit(struct fb_info *info, |
const struct fb_image *image); |
void drm_fb_helper_cfb_fillrect(struct fb_info *info, |
const struct fb_fillrect *rect); |
void drm_fb_helper_cfb_copyarea(struct fb_info *info, |
const struct fb_copyarea *area); |
void drm_fb_helper_cfb_imageblit(struct fb_info *info, |
const struct fb_image *image); |
void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state); |
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); |
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); |
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); |
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); |
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); |
int drm_fb_helper_debug_enter(struct fb_info *info); |
int drm_fb_helper_debug_leave(struct fb_info *info); |
139,4 → 211,188 |
int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector); |
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, |
struct drm_connector *connector); |
#else |
static inline void drm_fb_helper_prepare(struct drm_device *dev, |
struct drm_fb_helper *helper, |
const struct drm_fb_helper_funcs *funcs) |
{ |
} |
static inline int drm_fb_helper_init(struct drm_device *dev, |
struct drm_fb_helper *helper, int crtc_count, |
int max_conn) |
{ |
return 0; |
} |
static inline void drm_fb_helper_fini(struct drm_fb_helper *helper) |
{ |
} |
static inline int drm_fb_helper_blank(int blank, struct fb_info *info) |
{ |
return 0; |
} |
static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, |
struct fb_info *info) |
{ |
return 0; |
} |
static inline int drm_fb_helper_set_par(struct fb_info *info) |
{ |
return 0; |
} |
static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var, |
struct fb_info *info) |
{ |
return 0; |
} |
static inline int |
drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) |
{ |
return 0; |
} |
static inline struct fb_info * |
drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) |
{ |
return NULL; |
} |
static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) |
{ |
} |
static inline void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper) |
{ |
} |
static inline void drm_fb_helper_fill_var(struct fb_info *info, |
struct drm_fb_helper *fb_helper, |
uint32_t fb_width, uint32_t fb_height) |
{ |
} |
static inline void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, |
uint32_t depth) |
{ |
} |
static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap, |
struct fb_info *info) |
{ |
return 0; |
} |
static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) |
{ |
} |
static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info, |
char __user *buf, size_t count, |
loff_t *ppos) |
{ |
return -ENODEV; |
} |
static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info, |
const char __user *buf, |
size_t count, loff_t *ppos) |
{ |
return -ENODEV; |
} |
static inline void drm_fb_helper_sys_fillrect(struct fb_info *info, |
const struct fb_fillrect *rect) |
{ |
} |
static inline void drm_fb_helper_sys_copyarea(struct fb_info *info, |
const struct fb_copyarea *area) |
{ |
} |
static inline void drm_fb_helper_sys_imageblit(struct fb_info *info, |
const struct fb_image *image) |
{ |
} |
static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info, |
const struct fb_fillrect *rect) |
{ |
} |
static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info, |
const struct fb_copyarea *area) |
{ |
} |
static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info, |
const struct fb_image *image) |
{ |
} |
static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, |
int state) |
{ |
} |
static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) |
{ |
return 0; |
} |
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, |
int bpp_sel) |
{ |
return 0; |
} |
static inline int |
drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) |
{ |
return 0; |
} |
static inline int drm_fb_helper_debug_enter(struct fb_info *info) |
{ |
return 0; |
} |
static inline int drm_fb_helper_debug_leave(struct fb_info *info) |
{ |
return 0; |
} |
static inline struct drm_display_mode * |
drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, |
int width, int height) |
{ |
return NULL; |
} |
static inline struct drm_display_mode * |
drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, |
int width, int height) |
{ |
return NULL; |
} |
static inline int |
drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, |
struct drm_connector *connector) |
{ |
return 0; |
} |
static inline int |
drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, |
struct drm_connector *connector) |
{ |
return 0; |
} |
#endif |
#endif |
/drivers/include/drm/drm_gem.h |
---|
119,13 → 119,6 |
* simply leave it as NULL. |
*/ |
struct dma_buf_attachment *import_attach; |
/** |
* dumb - created as dumb buffer |
* Whether the gem object was created using the dumb buffer interface |
* as such it may not be used for GPU rendering. |
*/ |
bool dumb; |
}; |
void drm_gem_object_release(struct drm_gem_object *obj); |
/drivers/include/drm/drm_mipi_dsi.h |
---|
0,0 → 1,259 |
/* |
* MIPI DSI Bus |
* |
* Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. |
* Andrzej Hajda <a.hajda@samsung.com> |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License version 2 as |
* published by the Free Software Foundation. |
*/ |
#ifndef __DRM_MIPI_DSI_H__ |
#define __DRM_MIPI_DSI_H__ |
#include <linux/device.h> |
struct mipi_dsi_host; |
struct mipi_dsi_device; |
/* request ACK from peripheral */ |
#define MIPI_DSI_MSG_REQ_ACK BIT(0) |
/* use Low Power Mode to transmit message */ |
#define MIPI_DSI_MSG_USE_LPM BIT(1) |
/** |
* struct mipi_dsi_msg - read/write DSI buffer |
* @channel: virtual channel id |
* @type: payload data type |
* @flags: flags controlling this message transmission |
* @tx_len: length of @tx_buf |
* @tx_buf: data to be written |
* @rx_len: length of @rx_buf |
* @rx_buf: data to be read, or NULL |
*/ |
struct mipi_dsi_msg { |
u8 channel; |
u8 type; |
u16 flags; |
size_t tx_len; |
const void *tx_buf; |
size_t rx_len; |
void *rx_buf; |
}; |
bool mipi_dsi_packet_format_is_short(u8 type); |
bool mipi_dsi_packet_format_is_long(u8 type); |
/** |
* struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format |
* @size: size (in bytes) of the packet |
* @header: the four bytes that make up the header (Data ID, Word Count or |
* Packet Data, and ECC) |
* @payload_length: number of bytes in the payload |
* @payload: a pointer to a buffer containing the payload, if any |
*/ |
struct mipi_dsi_packet { |
size_t size; |
u8 header[4]; |
size_t payload_length; |
const u8 *payload; |
}; |
int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, |
const struct mipi_dsi_msg *msg); |
/** |
* struct mipi_dsi_host_ops - DSI bus operations |
* @attach: attach DSI device to DSI host |
* @detach: detach DSI device from DSI host |
* @transfer: transmit a DSI packet |
* |
* DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg |
* structures. This structure contains information about the type of packet |
* being transmitted as well as the transmit and receive buffers. When an |
* error is encountered during transmission, this function will return a |
* negative error code. On success it shall return the number of bytes |
* transmitted for write packets or the number of bytes received for read |
* packets. |
* |
* Note that typically DSI packet transmission is atomic, so the .transfer() |
* function will seldomly return anything other than the number of bytes |
* contained in the transmit buffer on success. |
*/ |
struct mipi_dsi_host_ops { |
int (*attach)(struct mipi_dsi_host *host, |
struct mipi_dsi_device *dsi); |
int (*detach)(struct mipi_dsi_host *host, |
struct mipi_dsi_device *dsi); |
ssize_t (*transfer)(struct mipi_dsi_host *host, |
const struct mipi_dsi_msg *msg); |
}; |
/** |
* struct mipi_dsi_host - DSI host device |
* @dev: driver model device node for this DSI host |
* @ops: DSI host operations |
*/ |
struct mipi_dsi_host { |
struct device *dev; |
const struct mipi_dsi_host_ops *ops; |
}; |
int mipi_dsi_host_register(struct mipi_dsi_host *host); |
void mipi_dsi_host_unregister(struct mipi_dsi_host *host); |
/* DSI mode flags */ |
/* video mode */ |
#define MIPI_DSI_MODE_VIDEO BIT(0) |
/* video burst mode */ |
#define MIPI_DSI_MODE_VIDEO_BURST BIT(1) |
/* video pulse mode */ |
#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2) |
/* enable auto vertical count mode */ |
#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3) |
/* enable hsync-end packets in vsync-pulse and v-porch area */ |
#define MIPI_DSI_MODE_VIDEO_HSE BIT(4) |
/* disable hfront-porch area */ |
#define MIPI_DSI_MODE_VIDEO_HFP BIT(5) |
/* disable hback-porch area */ |
#define MIPI_DSI_MODE_VIDEO_HBP BIT(6) |
/* disable hsync-active area */ |
#define MIPI_DSI_MODE_VIDEO_HSA BIT(7) |
/* flush display FIFO on vsync pulse */ |
#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8) |
/* disable EoT packets in HS mode */ |
#define MIPI_DSI_MODE_EOT_PACKET BIT(9) |
/* device supports non-continuous clock behavior (DSI spec 5.6.1) */ |
#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10) |
/* transmit data in low power */ |
#define MIPI_DSI_MODE_LPM BIT(11) |
enum mipi_dsi_pixel_format { |
MIPI_DSI_FMT_RGB888, |
MIPI_DSI_FMT_RGB666, |
MIPI_DSI_FMT_RGB666_PACKED, |
MIPI_DSI_FMT_RGB565, |
}; |
/** |
* struct mipi_dsi_device - DSI peripheral device |
* @host: DSI host for this peripheral |
* @dev: driver model device node for this peripheral |
* @channel: virtual channel assigned to the peripheral |
* @format: pixel format for video mode |
* @lanes: number of active data lanes |
* @mode_flags: DSI operation mode related flags |
*/ |
struct mipi_dsi_device { |
struct mipi_dsi_host *host; |
struct device dev; |
unsigned int channel; |
unsigned int lanes; |
enum mipi_dsi_pixel_format format; |
unsigned long mode_flags; |
}; |
static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) |
{ |
return container_of(dev, struct mipi_dsi_device, dev); |
} |
struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); |
int mipi_dsi_attach(struct mipi_dsi_device *dsi); |
int mipi_dsi_detach(struct mipi_dsi_device *dsi); |
int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, |
u16 value); |
ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, |
size_t size); |
ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, |
size_t num_params, void *data, size_t size); |
/** |
* enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode |
* @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking |
* information only |
* @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both |
* V-Blanking and H-Blanking information |
*/ |
enum mipi_dsi_dcs_tear_mode { |
MIPI_DSI_DCS_TEAR_MODE_VBLANK, |
MIPI_DSI_DCS_TEAR_MODE_VHBLANK, |
}; |
#define MIPI_DSI_DCS_POWER_MODE_DISPLAY (1 << 2) |
#define MIPI_DSI_DCS_POWER_MODE_NORMAL (1 << 3) |
#define MIPI_DSI_DCS_POWER_MODE_SLEEP (1 << 4) |
#define MIPI_DSI_DCS_POWER_MODE_PARTIAL (1 << 5) |
#define MIPI_DSI_DCS_POWER_MODE_IDLE (1 << 6) |
ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, |
const void *data, size_t len); |
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, |
const void *data, size_t len); |
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, |
size_t len); |
int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); |
int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format); |
int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, |
u16 end); |
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, |
u16 end); |
int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); |
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, |
enum mipi_dsi_dcs_tear_mode mode); |
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); |
/** |
* struct mipi_dsi_driver - DSI driver |
* @driver: device driver model driver |
* @probe: callback for device binding |
* @remove: callback for device unbinding |
* @shutdown: called at shutdown time to quiesce the device |
*/ |
struct mipi_dsi_driver { |
struct device_driver driver; |
int(*probe)(struct mipi_dsi_device *dsi); |
int(*remove)(struct mipi_dsi_device *dsi); |
void (*shutdown)(struct mipi_dsi_device *dsi); |
}; |
static inline struct mipi_dsi_driver * |
to_mipi_dsi_driver(struct device_driver *driver) |
{ |
return container_of(driver, struct mipi_dsi_driver, driver); |
} |
static inline void *mipi_dsi_get_drvdata(const struct mipi_dsi_device *dsi) |
{ |
return dev_get_drvdata(&dsi->dev); |
} |
static inline void mipi_dsi_set_drvdata(struct mipi_dsi_device *dsi, void *data) |
{ |
dev_set_drvdata(&dsi->dev, data); |
} |
int mipi_dsi_driver_register_full(struct mipi_dsi_driver *driver, |
struct module *owner); |
void mipi_dsi_driver_unregister(struct mipi_dsi_driver *driver); |
#define mipi_dsi_driver_register(driver) \ |
mipi_dsi_driver_register_full(driver, THIS_MODULE) |
#define module_mipi_dsi_driver(__mipi_dsi_driver) \ |
module_driver(__mipi_dsi_driver, mipi_dsi_driver_register, \ |
mipi_dsi_driver_unregister) |
#endif /* __DRM_MIPI_DSI__ */ |
/drivers/include/drm/drm_mm.h |
---|
68,8 → 68,8 |
unsigned scanned_preceeds_hole : 1; |
unsigned allocated : 1; |
unsigned long color; |
unsigned long start; |
unsigned long size; |
u64 start; |
u64 size; |
struct drm_mm *mm; |
}; |
82,16 → 82,16 |
unsigned int scan_check_range : 1; |
unsigned scan_alignment; |
unsigned long scan_color; |
unsigned long scan_size; |
unsigned long scan_hit_start; |
unsigned long scan_hit_end; |
u64 scan_size; |
u64 scan_hit_start; |
u64 scan_hit_end; |
unsigned scanned_blocks; |
unsigned long scan_start; |
unsigned long scan_end; |
u64 scan_start; |
u64 scan_end; |
struct drm_mm_node *prev_scanned_node; |
void (*color_adjust)(struct drm_mm_node *node, unsigned long color, |
unsigned long *start, unsigned long *end); |
u64 *start, u64 *end); |
}; |
/** |
124,7 → 124,7 |
return mm->hole_stack.next; |
} |
static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
static inline u64 __drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
{ |
return hole_node->start + hole_node->size; |
} |
140,13 → 140,13 |
* Returns: |
* Start of the subsequent hole. |
*/ |
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
static inline u64 drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
{ |
BUG_ON(!hole_node->hole_follows); |
return __drm_mm_hole_node_start(hole_node); |
} |
static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
static inline u64 __drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
{ |
return list_entry(hole_node->node_list.next, |
struct drm_mm_node, node_list)->start; |
163,7 → 163,7 |
* Returns: |
* End of the subsequent hole. |
*/ |
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
static inline u64 drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
{ |
return __drm_mm_hole_node_end(hole_node); |
} |
222,7 → 222,7 |
int drm_mm_insert_node_generic(struct drm_mm *mm, |
struct drm_mm_node *node, |
unsigned long size, |
u64 size, |
unsigned alignment, |
unsigned long color, |
enum drm_mm_search_flags sflags, |
245,7 → 245,7 |
*/ |
static inline int drm_mm_insert_node(struct drm_mm *mm, |
struct drm_mm_node *node, |
unsigned long size, |
u64 size, |
unsigned alignment, |
enum drm_mm_search_flags flags) |
{ |
255,11 → 255,11 |
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, |
struct drm_mm_node *node, |
unsigned long size, |
u64 size, |
unsigned alignment, |
unsigned long color, |
unsigned long start, |
unsigned long end, |
u64 start, |
u64 end, |
enum drm_mm_search_flags sflags, |
enum drm_mm_allocator_flags aflags); |
/** |
282,10 → 282,10 |
*/ |
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, |
struct drm_mm_node *node, |
unsigned long size, |
u64 size, |
unsigned alignment, |
unsigned long start, |
unsigned long end, |
u64 start, |
u64 end, |
enum drm_mm_search_flags flags) |
{ |
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, |
296,21 → 296,21 |
void drm_mm_remove_node(struct drm_mm_node *node); |
void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); |
void drm_mm_init(struct drm_mm *mm, |
unsigned long start, |
unsigned long size); |
u64 start, |
u64 size); |
void drm_mm_takedown(struct drm_mm *mm); |
bool drm_mm_clean(struct drm_mm *mm); |
void drm_mm_init_scan(struct drm_mm *mm, |
unsigned long size, |
u64 size, |
unsigned alignment, |
unsigned long color); |
void drm_mm_init_scan_with_range(struct drm_mm *mm, |
unsigned long size, |
u64 size, |
unsigned alignment, |
unsigned long color, |
unsigned long start, |
unsigned long end); |
u64 start, |
u64 end); |
bool drm_mm_scan_add_block(struct drm_mm_node *node); |
bool drm_mm_scan_remove_block(struct drm_mm_node *node); |
/drivers/include/drm/drm_modes.h |
---|
90,6 → 90,9 |
#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */ |
#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */ |
#define CRTC_NO_DBLSCAN (1 << 2) /* don't adjust doublescan */ |
#define CRTC_NO_VSCAN (1 << 3) /* don't adjust doublescan */ |
#define CRTC_STEREO_DOUBLE_ONLY (CRTC_STEREO_DOUBLE | CRTC_NO_DBLSCAN | CRTC_NO_VSCAN) |
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF |
179,6 → 182,10 |
struct drm_display_mode *drm_mode_create(struct drm_device *dev); |
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); |
void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, |
const struct drm_display_mode *in); |
int drm_mode_convert_umode(struct drm_display_mode *out, |
const struct drm_mode_modeinfo *in); |
void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); |
void drm_mode_debug_printmodeline(const struct drm_display_mode *mode); |
197,6 → 204,8 |
int GTF_K, int GTF_2J); |
void drm_display_mode_from_videomode(const struct videomode *vm, |
struct drm_display_mode *dmode); |
void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, |
struct videomode *vm); |
int of_get_drm_display_mode(struct device_node *np, |
struct drm_display_mode *dmode, |
int index); |
217,8 → 226,8 |
const struct drm_display_mode *mode2); |
/* for use by the crtc helper probe functions */ |
void drm_mode_validate_size(struct drm_device *dev, |
struct list_head *mode_list, |
enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode); |
enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode, |
int maxX, int maxY); |
void drm_mode_prune_invalid(struct drm_device *dev, |
struct list_head *mode_list, bool verbose); |
/drivers/include/drm/drm_modeset_lock.h |
---|
43,7 → 43,7 |
struct ww_acquire_ctx ww_ctx; |
/** |
/* |
* Contended lock: if a lock is contended you should only call |
* drm_modeset_backoff() which drops locks and slow-locks the |
* contended lock. |
50,12 → 50,12 |
*/ |
struct drm_modeset_lock *contended; |
/** |
/* |
* list of held locks (drm_modeset_lock) |
*/ |
struct list_head locked; |
/** |
/* |
* Trylock mode, use only for panic handlers! |
*/ |
bool trylock_only; |
70,12 → 70,12 |
* Used for locking CRTCs and other modeset resources. |
*/ |
struct drm_modeset_lock { |
/** |
/* |
* modeset lock |
*/ |
struct ww_mutex mutex; |
/** |
/* |
* Resources that are locked as part of an atomic update are added |
* to a list (so we know what to unlock at the end). |
*/ |
130,7 → 130,6 |
struct drm_plane; |
void drm_modeset_lock_all(struct drm_device *dev); |
int __drm_modeset_lock_all(struct drm_device *dev, bool trylock); |
void drm_modeset_unlock_all(struct drm_device *dev); |
void drm_modeset_lock_crtc(struct drm_crtc *crtc, |
struct drm_plane *plane); |
/drivers/include/drm/drm_panel.h |
---|
0,0 → 1,145 |
/* |
* Copyright (C) 2013, NVIDIA Corporation. All rights reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sub license, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#ifndef __DRM_PANEL_H__ |
#define __DRM_PANEL_H__ |
#include <linux/list.h> |
struct drm_connector; |
struct drm_device; |
struct drm_panel; |
struct display_timing; |
/** |
* struct drm_panel_funcs - perform operations on a given panel |
* @disable: disable panel (turn off back light, etc.) |
* @unprepare: turn off panel |
* @prepare: turn on panel and perform set up |
* @enable: enable panel (turn on back light, etc.) |
* @get_modes: add modes to the connector that the panel is attached to and |
* return the number of modes added |
* @get_timings: copy display timings into the provided array and return |
* the number of display timings available |
* |
* The .prepare() function is typically called before the display controller |
* starts to transmit video data. Panel drivers can use this to turn the panel |
* on and wait for it to become ready. If additional configuration is required |
* (via a control bus such as I2C, SPI or DSI for example) this is a good time |
* to do that. |
* |
* After the display controller has started transmitting video data, it's safe |
* to call the .enable() function. This will typically enable the backlight to |
* make the image on screen visible. Some panels require a certain amount of |
* time or frames before the image is displayed. This function is responsible |
* for taking this into account before enabling the backlight to avoid visual |
* glitches. |
* |
* Before stopping video transmission from the display controller it can be |
* necessary to turn off the panel to avoid visual glitches. This is done in |
* the .disable() function. Analogously to .enable() this typically involves |
* turning off the backlight and waiting for some time to make sure no image |
* is visible on the panel. It is then safe for the display controller to |
* cease transmission of video data. |
* |
* To save power when no video data is transmitted, a driver can power down |
* the panel. This is the job of the .unprepare() function. |
*/ |
struct drm_panel_funcs { |
int (*disable)(struct drm_panel *panel); |
int (*unprepare)(struct drm_panel *panel); |
int (*prepare)(struct drm_panel *panel); |
int (*enable)(struct drm_panel *panel); |
int (*get_modes)(struct drm_panel *panel); |
int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, |
struct display_timing *timings); |
}; |
struct drm_panel { |
struct drm_device *drm; |
struct drm_connector *connector; |
struct device *dev; |
const struct drm_panel_funcs *funcs; |
struct list_head list; |
}; |
static inline int drm_panel_unprepare(struct drm_panel *panel) |
{ |
if (panel && panel->funcs && panel->funcs->unprepare) |
return panel->funcs->unprepare(panel); |
return panel ? -ENOSYS : -EINVAL; |
} |
static inline int drm_panel_disable(struct drm_panel *panel) |
{ |
if (panel && panel->funcs && panel->funcs->disable) |
return panel->funcs->disable(panel); |
return panel ? -ENOSYS : -EINVAL; |
} |
static inline int drm_panel_prepare(struct drm_panel *panel) |
{ |
if (panel && panel->funcs && panel->funcs->prepare) |
return panel->funcs->prepare(panel); |
return panel ? -ENOSYS : -EINVAL; |
} |
static inline int drm_panel_enable(struct drm_panel *panel) |
{ |
if (panel && panel->funcs && panel->funcs->enable) |
return panel->funcs->enable(panel); |
return panel ? -ENOSYS : -EINVAL; |
} |
static inline int drm_panel_get_modes(struct drm_panel *panel) |
{ |
if (panel && panel->funcs && panel->funcs->get_modes) |
return panel->funcs->get_modes(panel); |
return panel ? -ENOSYS : -EINVAL; |
} |
void drm_panel_init(struct drm_panel *panel); |
int drm_panel_add(struct drm_panel *panel); |
void drm_panel_remove(struct drm_panel *panel); |
int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector); |
int drm_panel_detach(struct drm_panel *panel); |
#ifdef CONFIG_OF |
struct drm_panel *of_drm_find_panel(struct device_node *np); |
#else |
static inline struct drm_panel *of_drm_find_panel(struct device_node *np) |
{ |
return NULL; |
} |
#endif |
#endif |
/drivers/include/drm/drm_pciids.h |
---|
172,6 → 172,7 |
{0x1002, 0x6610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6611, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6613, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6617, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6620, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6623, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
186,6 → 187,7 |
{0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x665f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
{0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
/drivers/include/drm/drm_plane_helper.h |
---|
43,8 → 43,7 |
* planes. |
*/ |
extern int drm_crtc_init(struct drm_device *dev, |
struct drm_crtc *crtc, |
int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
const struct drm_crtc_funcs *funcs); |
/** |
52,29 → 51,32 |
* @prepare_fb: prepare a framebuffer for use by the plane |
* @cleanup_fb: cleanup a framebuffer when it's no longer used by the plane |
* @atomic_check: check that a given atomic state is valid and can be applied |
* @atomic_update: apply an atomic state to the plane |
* @atomic_update: apply an atomic state to the plane (mandatory) |
* @atomic_disable: disable the plane |
* |
* The helper operations are called by the mid-layer CRTC helper. |
*/ |
struct drm_plane_helper_funcs { |
int (*prepare_fb)(struct drm_plane *plane, |
struct drm_framebuffer *fb); |
const struct drm_plane_state *new_state); |
void (*cleanup_fb)(struct drm_plane *plane, |
struct drm_framebuffer *fb); |
const struct drm_plane_state *old_state); |
int (*atomic_check)(struct drm_plane *plane, |
struct drm_plane_state *state); |
void (*atomic_update)(struct drm_plane *plane, |
struct drm_plane_state *old_state); |
void (*atomic_disable)(struct drm_plane *plane, |
struct drm_plane_state *old_state); |
}; |
static inline void drm_plane_helper_add(struct drm_plane *plane, |
const struct drm_plane_helper_funcs *funcs) |
{ |
plane->helper_private = (void *)funcs; |
plane->helper_private = funcs; |
} |
extern int drm_plane_helper_check_update(struct drm_plane *plane, |
int drm_plane_helper_check_update(struct drm_plane *plane, |
struct drm_crtc *crtc, |
struct drm_framebuffer *fb, |
struct drm_rect *src, |
85,7 → 87,7 |
bool can_position, |
bool can_update_disabled, |
bool *visible); |
extern int drm_primary_helper_update(struct drm_plane *plane, |
int drm_primary_helper_update(struct drm_plane *plane, |
struct drm_crtc *crtc, |
struct drm_framebuffer *fb, |
int crtc_x, int crtc_y, |
92,14 → 94,10 |
unsigned int crtc_w, unsigned int crtc_h, |
uint32_t src_x, uint32_t src_y, |
uint32_t src_w, uint32_t src_h); |
extern int drm_primary_helper_disable(struct drm_plane *plane); |
extern void drm_primary_helper_destroy(struct drm_plane *plane); |
int drm_primary_helper_disable(struct drm_plane *plane); |
void drm_primary_helper_destroy(struct drm_plane *plane); |
extern const struct drm_plane_funcs drm_primary_helper_funcs; |
extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, |
const uint32_t *formats, |
int num_formats); |
int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, |
struct drm_framebuffer *fb, |
int crtc_x, int crtc_y, |
/drivers/include/drm/drm_vma_manager.h |
---|
54,9 → 54,6 |
unsigned long page_offset, unsigned long size); |
void drm_vma_offset_manager_destroy(struct drm_vma_offset_manager *mgr); |
struct drm_vma_offset_node *drm_vma_offset_lookup(struct drm_vma_offset_manager *mgr, |
unsigned long start, |
unsigned long pages); |
struct drm_vma_offset_node *drm_vma_offset_lookup_locked(struct drm_vma_offset_manager *mgr, |
unsigned long start, |
unsigned long pages); |
71,12 → 68,12 |
struct file *filp); |
/** |
* drm_vma_offset_exact_lookup() - Look up node by exact address |
* drm_vma_offset_exact_lookup_locked() - Look up node by exact address |
* @mgr: Manager object |
* @start: Start address (page-based, not byte-based) |
* @pages: Size of object (page-based) |
* |
* Same as drm_vma_offset_lookup() but does not allow any offset into the node. |
* Same as drm_vma_offset_lookup_locked() but does not allow any offset into the node. |
* It only returns the exact object with the given start address. |
* |
* RETURNS: |
83,13 → 80,13 |
* Node at exact start address @start. |
*/ |
static inline struct drm_vma_offset_node * |
drm_vma_offset_exact_lookup(struct drm_vma_offset_manager *mgr, |
drm_vma_offset_exact_lookup_locked(struct drm_vma_offset_manager *mgr, |
unsigned long start, |
unsigned long pages) |
{ |
struct drm_vma_offset_node *node; |
node = drm_vma_offset_lookup(mgr, start, pages); |
node = drm_vma_offset_lookup_locked(mgr, start, pages); |
return (node && node->vm_node.start == start) ? node : NULL; |
} |
97,7 → 94,7 |
* drm_vma_offset_lock_lookup() - Lock lookup for extended private use |
* @mgr: Manager object |
* |
* Lock VMA manager for extended lookups. Only *_locked() VMA function calls |
* Lock VMA manager for extended lookups. Only locked VMA function calls |
* are allowed while holding this lock. All other contexts are blocked from VMA |
* until the lock is released via drm_vma_offset_unlock_lookup(). |
* |
108,13 → 105,6 |
* not call any other VMA helpers while holding this lock. |
* |
* Note: You're in atomic-context while holding this lock! |
* |
* Example: |
* drm_vma_offset_lock_lookup(mgr); |
* node = drm_vma_offset_lookup_locked(mgr); |
* if (node) |
* kref_get_unless_zero(container_of(node, sth, entr)); |
* drm_vma_offset_unlock_lookup(mgr); |
*/ |
static inline void drm_vma_offset_lock_lookup(struct drm_vma_offset_manager *mgr) |
{ |
/drivers/include/drm/i915_component.h |
---|
0,0 → 1,78 |
/* |
* Copyright © 2014 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
#ifndef _I915_COMPONENT_H_ |
#define _I915_COMPONENT_H_ |
/* MAX_PORT is the number of port |
* It must be sync with I915_MAX_PORTS defined i915_drv.h |
* 5 should be enough as only HSW, BDW, SKL need such fix. |
*/ |
#define MAX_PORTS 5 |
/** |
* struct i915_audio_component_ops - callbacks defined in gfx driver |
* @owner: the module owner |
* @get_power: get the POWER_DOMAIN_AUDIO power well |
* @put_power: put the POWER_DOMAIN_AUDIO power well |
* @codec_wake_override: Enable/Disable generating the codec wake signal |
* @get_cdclk_freq: get the Core Display Clock in KHz |
* @sync_audio_rate: set n/cts based on the sample rate |
*/ |
struct i915_audio_component_ops { |
struct module *owner; |
void (*get_power)(struct device *); |
void (*put_power)(struct device *); |
void (*codec_wake_override)(struct device *, bool enable); |
int (*get_cdclk_freq)(struct device *); |
int (*sync_audio_rate)(struct device *, int port, int rate); |
}; |
struct i915_audio_component_audio_ops { |
void *audio_ptr; |
/** |
* Call from i915 driver, notifying the HDA driver that |
* pin sense and/or ELD information has changed. |
* @audio_ptr: HDA driver object |
* @port: Which port has changed (PORTA / PORTB / PORTC etc) |
*/ |
void (*pin_eld_notify)(void *audio_ptr, int port); |
}; |
/** |
* struct i915_audio_component - used for audio video interaction |
* @dev: the device from gfx driver |
* @aud_sample_rate: the array of audio sample rate per port |
* @ops: callback for audio driver calling |
* @audio_ops: Call from i915 driver |
*/ |
struct i915_audio_component { |
struct device *dev; |
int aud_sample_rate[MAX_PORTS]; |
const struct i915_audio_component_ops *ops; |
const struct i915_audio_component_audio_ops *audio_ops; |
}; |
#endif /* _I915_COMPONENT_H_ */ |
/drivers/include/drm/i915_pciids.h |
---|
208,40 → 208,41 |
#define INTEL_VLV_D_IDS(info) \ |
INTEL_VGA_DEVICE(0x0155, info) |
#define _INTEL_BDW_M(gt, id, info) \ |
INTEL_VGA_DEVICE((((gt) - 1) << 4) | (id), info) |
#define _INTEL_BDW_D(gt, id, info) \ |
INTEL_VGA_DEVICE((((gt) - 1) << 4) | (id), info) |
#define _INTEL_BDW_M_IDS(gt, info) \ |
_INTEL_BDW_M(gt, 0x1602, info), /* ULT */ \ |
_INTEL_BDW_M(gt, 0x1606, info), /* ULT */ \ |
_INTEL_BDW_M(gt, 0x160B, info), /* Iris */ \ |
_INTEL_BDW_M(gt, 0x160E, info) /* ULX */ |
#define _INTEL_BDW_D_IDS(gt, info) \ |
_INTEL_BDW_D(gt, 0x160A, info), /* Server */ \ |
_INTEL_BDW_D(gt, 0x160D, info) /* Workstation */ |
#define INTEL_BDW_GT12M_IDS(info) \ |
_INTEL_BDW_M_IDS(1, info), \ |
_INTEL_BDW_M_IDS(2, info) |
INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \ |
INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \ |
INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \ |
INTEL_VGA_DEVICE(0x160E, info), /* GT1 ULX */ \ |
INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \ |
INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \ |
INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \ |
INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */ |
#define INTEL_BDW_GT12D_IDS(info) \ |
_INTEL_BDW_D_IDS(1, info), \ |
_INTEL_BDW_D_IDS(2, info) |
INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \ |
INTEL_VGA_DEVICE(0x160D, info), /* GT1 Workstation */ \ |
INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \ |
INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */ |
#define INTEL_BDW_GT3M_IDS(info) \ |
_INTEL_BDW_M_IDS(3, info) |
INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \ |
INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \ |
INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \ |
INTEL_VGA_DEVICE(0x162E, info) /* ULX */ |
#define INTEL_BDW_GT3D_IDS(info) \ |
_INTEL_BDW_D_IDS(3, info) |
INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ |
INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ |
#define INTEL_BDW_RSVDM_IDS(info) \ |
_INTEL_BDW_M_IDS(4, info) |
INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ |
INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ |
INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \ |
INTEL_VGA_DEVICE(0x163E, info) /* ULX */ |
#define INTEL_BDW_RSVDD_IDS(info) \ |
_INTEL_BDW_D_IDS(4, info) |
INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ |
INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ |
#define INTEL_BDW_M_IDS(info) \ |
INTEL_BDW_GT12M_IDS(info), \ |
259,21 → 260,35 |
INTEL_VGA_DEVICE(0x22b2, info), \ |
INTEL_VGA_DEVICE(0x22b3, info) |
#define INTEL_SKL_IDS(info) \ |
#define INTEL_SKL_GT1_IDS(info) \ |
INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ |
INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ |
INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ |
INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ |
INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */ |
#define INTEL_SKL_GT2_IDS(info) \ |
INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ |
INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ |
INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \ |
INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ |
INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \ |
INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \ |
INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ |
INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \ |
INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ |
INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ |
INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \ |
INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \ |
INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \ |
INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ |
#define INTEL_SKL_GT3_IDS(info) \ |
INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ |
INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ \ |
#define INTEL_SKL_IDS(info) \ |
INTEL_SKL_GT1_IDS(info), \ |
INTEL_SKL_GT2_IDS(info), \ |
INTEL_SKL_GT3_IDS(info) |
#define INTEL_BXT_IDS(info) \ |
INTEL_VGA_DEVICE(0x0A84, info), \ |
INTEL_VGA_DEVICE(0x1A84, info), \ |
INTEL_VGA_DEVICE(0x5A84, info) |
#endif /* _I915_PCIIDS_H */ |
/drivers/include/drm/intel-gtt.h |
---|
3,8 → 3,8 |
#ifndef _DRM_INTEL_GTT_H |
#define _DRM_INTEL_GTT_H |
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, |
phys_addr_t *mappable_base, unsigned long *mappable_end); |
void intel_gtt_get(u64 *gtt_total, size_t *stolen_size, |
phys_addr_t *mappable_base, u64 *mappable_end); |
int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, |
struct agp_bridge_data *bridge); |
/drivers/include/drm/ttm/ttm_bo_api.h |
---|
249,7 → 249,7 |
* either of these locks held. |
*/ |
unsigned long offset; |
uint64_t offset; /* GPU address space is independent of CPU word size */ |
uint32_t cur_placement; |
struct sg_table *sg; |
/drivers/include/drm/ttm/ttm_bo_driver.h |
---|
277,7 → 277,7 |
bool has_type; |
bool use_type; |
uint32_t flags; |
unsigned long gpu_offset; |
uint64_t gpu_offset; /* GPU address space is independent of CPU word size */ |
uint64_t size; |
uint32_t available_caching; |
uint32_t default_caching; |
/drivers/include/drm/ttm/ttm_lock.h |
---|
51,7 → 51,7 |
#include <ttm/ttm_object.h> |
#include <linux/wait.h> |
//#include <linux/atomic.h> |
#include <linux/atomic.h> |
/** |
* struct ttm_lock |