/drivers/include/drm/drmP.h |
---|
50,6 → 50,7 |
#include <linux/mutex.h> |
#include <linux/pci.h> |
#include <linux/sched.h> |
#include <linux/wait.h> |
#include <linux/firmware.h> |
#include <linux/err.h> |
919,8 → 920,7 |
#endif |
extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, |
struct drm_gem_object *obj, |
int flags); |
struct drm_gem_object *obj, int flags); |
extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, |
struct drm_file *file_priv, uint32_t handle, uint32_t flags, |
int *prime_fd); |
950,7 → 950,7 |
void drm_dev_unref(struct drm_device *dev); |
int drm_dev_register(struct drm_device *dev, unsigned long flags); |
void drm_dev_unregister(struct drm_device *dev); |
int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...); |
int drm_dev_set_unique(struct drm_device *dev, const char *name); |
struct drm_minor *drm_minor_acquire(unsigned int minor_id); |
void drm_minor_release(struct drm_minor *minor); |
971,6 → 971,11 |
extern int drm_get_pci_dev(struct pci_dev *pdev, |
const struct pci_device_id *ent, |
struct drm_driver *driver); |
static inline int drm_pci_set_busid(struct drm_device *dev, |
struct drm_master *master) |
{ |
return -ENOSYS; |
} |
#endif |
#define DRM_PCIE_SPEED_25 1 |
978,7 → 983,12 |
#define DRM_PCIE_SPEED_80 4 |
extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); |
extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); |
/* platform section */ |
extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); |
extern int drm_platform_set_busid(struct drm_device *d, struct drm_master *m); |
/* returns true if currently okay to sleep */ |
static __inline__ bool drm_can_sleep(void) |
{ |
985,6 → 995,9 |
return true; |
} |
/* helper for handling conditionals in various for_each macros */ |
#define for_each_if(condition) if (!(condition)) {} else |
static __inline__ int drm_device_is_pcie(struct drm_device *dev) |
{ |
return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); |
/drivers/include/drm/drm_atomic.h |
---|
130,10 → 130,6 |
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); |
void drm_atomic_legacy_backoff(struct drm_atomic_state *state); |
void |
149,7 → 145,7 |
((connector) = (state)->connectors[__i], \ |
(connector_state) = (state)->connector_states[__i], 1); \ |
(__i)++) \ |
if (connector) |
for_each_if (connector) |
#define for_each_crtc_in_state(state, crtc, crtc_state, __i) \ |
for ((__i) = 0; \ |
157,7 → 153,7 |
((crtc) = (state)->crtcs[__i], \ |
(crtc_state) = (state)->crtc_states[__i], 1); \ |
(__i)++) \ |
if (crtc_state) |
for_each_if (crtc_state) |
#define for_each_plane_in_state(state, plane, plane_state, __i) \ |
for ((__i) = 0; \ |
165,7 → 161,7 |
((plane) = (state)->planes[__i], \ |
(plane_state) = (state)->plane_states[__i], 1); \ |
(__i)++) \ |
if (plane_state) |
for_each_if (plane_state) |
static inline bool |
drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) |
{ |
/drivers/include/drm/drm_atomic_helper.h |
---|
42,6 → 42,10 |
struct drm_atomic_state *state, |
bool async); |
bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev, |
struct drm_atomic_state *old_state, |
struct drm_crtc *crtc); |
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, |
struct drm_atomic_state *old_state); |
62,6 → 66,8 |
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_disable_planes_on_crtc(struct drm_crtc *crtc, |
bool atomic); |
void drm_atomic_helper_swap_state(struct drm_device *dev, |
struct drm_atomic_state *state); |
81,6 → 87,12 |
int __drm_atomic_helper_set_config(struct drm_mode_set *set, |
struct drm_atomic_state *state); |
int drm_atomic_helper_disable_all(struct drm_device *dev, |
struct drm_modeset_acquire_ctx *ctx); |
struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev); |
int drm_atomic_helper_resume(struct drm_device *dev, |
struct drm_atomic_state *state); |
int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, |
struct drm_property *property, |
uint64_t val); |
118,6 → 130,8 |
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, |
struct drm_connector_state *conn_state); |
void drm_atomic_helper_connector_reset(struct drm_connector *connector); |
void |
__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, |
/drivers/include/drm/drm_crtc.h |
---|
85,7 → 85,11 |
return (uint64_t)*((uint64_t *)&val); |
} |
/* rotation property bits */ |
/* |
* Rotation property bits. DRM_ROTATE_<degrees> rotates the image by the |
* specified amount in degrees in counter clockwise direction. DRM_REFLECT_X and |
* DRM_REFLECT_Y reflects the image along the specified axis prior to rotation |
*/ |
#define DRM_ROTATE_MASK 0x0f |
#define DRM_ROTATE_0 0 |
#define DRM_ROTATE_90 1 |
158,23 → 162,60 |
u8 group_data[8]; |
}; |
/** |
* struct drm_framebuffer_funcs - framebuffer hooks |
*/ |
struct drm_framebuffer_funcs { |
/* note: use drm_framebuffer_remove() */ |
/** |
* @destroy: |
* |
* Clean up framebuffer resources, specifically also unreference the |
* backing storage. The core guarantees to call this function for every |
* framebuffer successfully created by ->fb_create() in |
* &drm_mode_config_funcs. Drivers must also call |
* drm_framebuffer_cleanup() to release DRM core resources for this |
* framebuffer. |
*/ |
void (*destroy)(struct drm_framebuffer *framebuffer); |
/** |
* @create_handle: |
* |
* Create a buffer handle in the driver-specific buffer manager (either |
* GEM or TTM) valid for the passed-in struct &drm_file. This is used by |
* the core to implement the GETFB IOCTL, which returns (for |
* sufficiently priviledged user) also a native buffer handle. This can |
* be used for seamless transitions between modesetting clients by |
* copying the current screen contents to a private buffer and blending |
* between that and the new contents. |
* |
* GEM based drivers should call drm_gem_handle_create() to create the |
* handle. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*create_handle)(struct drm_framebuffer *fb, |
struct drm_file *file_priv, |
unsigned int *handle); |
/* |
* Optional callback for the dirty fb ioctl. |
/** |
* @dirty: |
* |
* Userspace can notify the driver via this callback |
* that a area of the framebuffer has changed and should |
* be flushed to the display hardware. |
* Optional callback for the dirty fb IOCTL. |
* |
* See documentation in drm_mode.h for the struct |
* drm_mode_fb_dirty_cmd for more information as all |
* the semantics and arguments have a one to one mapping |
* on this function. |
* Userspace can notify the driver via this callback that an area of the |
* framebuffer has changed and should be flushed to the display |
* hardware. This can also be used internally, e.g. by the fbdev |
* emulation, though that's not the case currently. |
* |
* See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd |
* for more information as all the semantics and arguments have a one to |
* one mapping on this function. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*dirty)(struct drm_framebuffer *framebuffer, |
struct drm_file *file_priv, unsigned flags, |
250,6 → 291,11 |
struct drm_bridge; |
struct drm_atomic_state; |
struct drm_crtc_helper_funcs; |
struct drm_encoder_helper_funcs; |
struct drm_connector_helper_funcs; |
struct drm_plane_helper_funcs; |
/** |
* struct drm_crtc_state - mutable CRTC state |
* @crtc: backpointer to the CRTC |
260,6 → 306,7 |
* @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 |
* @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors |
* @last_vblank_count: for helpers and drivers to capture the vblank of the |
* update to ensure framebuffer cleanup isn't done too early |
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings |
293,6 → 340,8 |
*/ |
u32 plane_mask; |
u32 connector_mask; |
/* last_vblank_count: for vblank waits before cleanup */ |
u32 last_vblank_count; |
311,23 → 360,6 |
/** |
* struct drm_crtc_funcs - control CRTCs for a given device |
* @save: save CRTC state |
* @restore: restore CRTC state |
* @reset: reset CRTC after state has been invalidated (e.g. resume) |
* @cursor_set: setup the cursor |
* @cursor_set2: setup the cursor with hotspot, superseeds @cursor_set if set |
* @cursor_move: move the cursor |
* @gamma_set: specify color ramp for CRTC |
* @destroy: deinit and free object |
* @set_property: called when a property is changed |
* @set_config: apply a new CRTC configuration |
* @page_flip: initiate a page flip |
* @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 |
339,37 → 371,188 |
* bus accessors. |
*/ |
struct drm_crtc_funcs { |
/* Save CRTC state */ |
void (*save)(struct drm_crtc *crtc); /* suspend? */ |
/* Restore CRTC state */ |
void (*restore)(struct drm_crtc *crtc); /* resume? */ |
/* Reset CRTC state */ |
/** |
* @reset: |
* |
* Reset CRTC hardware and software state to off. This function isn't |
* called by the core directly, only through drm_mode_config_reset(). |
* It's not a helper hook only for historical reasons. |
* |
* Atomic drivers can use drm_atomic_helper_crtc_reset() to reset |
* atomic state using this hook. |
*/ |
void (*reset)(struct drm_crtc *crtc); |
/* cursor controls */ |
/** |
* @cursor_set: |
* |
* Update the cursor image. The cursor position is relative to the CRTC |
* and can be partially or fully outside of the visible area. |
* |
* Note that contrary to all other KMS functions the legacy cursor entry |
* points don't take a framebuffer object, but instead take directly a |
* raw buffer object id from the driver's buffer manager (which is |
* either GEM or TTM for current drivers). |
* |
* This entry point is deprecated, drivers should instead implement |
* universal plane support and register a proper cursor plane using |
* drm_crtc_init_with_planes(). |
* |
* This callback is optional |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, |
uint32_t handle, uint32_t width, uint32_t height); |
/** |
* @cursor_set2: |
* |
* Update the cursor image, including hotspot information. The hotspot |
* must not affect the cursor position in CRTC coordinates, but is only |
* meant as a hint for virtualized display hardware to coordinate the |
* guests and hosts cursor position. The cursor hotspot is relative to |
* the cursor image. Otherwise this works exactly like @cursor_set. |
* |
* This entry point is deprecated, drivers should instead implement |
* universal plane support and register a proper cursor plane using |
* drm_crtc_init_with_planes(). |
* |
* This callback is optional. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv, |
uint32_t handle, uint32_t width, uint32_t height, |
int32_t hot_x, int32_t hot_y); |
/** |
* @cursor_move: |
* |
* Update the cursor position. The cursor does not need to be visible |
* when this hook is called. |
* |
* This entry point is deprecated, drivers should instead implement |
* universal plane support and register a proper cursor plane using |
* drm_crtc_init_with_planes(). |
* |
* This callback is optional. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*cursor_move)(struct drm_crtc *crtc, int x, int y); |
/* Set gamma on the CRTC */ |
/** |
* @gamma_set: |
* |
* Set gamma on the CRTC. |
* |
* This callback is optional. |
* |
* NOTE: |
* |
* Drivers that support gamma tables and also fbdev emulation through |
* the provided helper library need to take care to fill out the gamma |
* hooks for both. Currently there's a bit an unfortunate duplication |
* going on, which should eventually be unified to just one set of |
* hooks. |
*/ |
void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, |
uint32_t start, uint32_t size); |
/* Object destroy routine */ |
/** |
* @destroy: |
* |
* Clean up plane resources. This is only called at driver unload time |
* through drm_mode_config_cleanup() since a CRTC cannot be hotplugged |
* in DRM. |
*/ |
void (*destroy)(struct drm_crtc *crtc); |
/** |
* @set_config: |
* |
* This is the main legacy entry point to change the modeset state on a |
* CRTC. All the details of the desired configuration are passed in a |
* struct &drm_mode_set - see there for details. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_set_config() to implement this hook. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*set_config)(struct drm_mode_set *set); |
/* |
* Flip to the given framebuffer. This implements the page |
* flip ioctl described in drm_mode.h, specifically, the |
* implementation must return immediately and block all |
* rendering to the current fb until the flip has completed. |
* If userspace set the event flag in the ioctl, the event |
* argument will point to an event to send back when the flip |
* completes, otherwise it will be NULL. |
/** |
* @page_flip: |
* |
* Legacy entry point to schedule a flip to the given framebuffer. |
* |
* Page flipping is a synchronization mechanism that replaces the frame |
* buffer being scanned out by the CRTC with a new frame buffer during |
* vertical blanking, avoiding tearing (except when requested otherwise |
* through the DRM_MODE_PAGE_FLIP_ASYNC flag). When an application |
* requests a page flip the DRM core verifies that the new frame buffer |
* is large enough to be scanned out by the CRTC in the currently |
* configured mode and then calls the CRTC ->page_flip() operation with a |
* pointer to the new frame buffer. |
* |
* The driver must wait for any pending rendering to the new framebuffer |
* to complete before executing the flip. It should also wait for any |
* pending rendering from other drivers if the underlying buffer is a |
* shared dma-buf. |
* |
* An application can request to be notified when the page flip has |
* completed. The drm core will supply a struct &drm_event in the event |
* parameter in this case. This can be handled by the |
* drm_crtc_send_vblank_event() function, which the driver should call on |
* the provided event upon completion of the flip. Note that if |
* the driver supports vblank signalling and timestamping the vblank |
* counters and timestamps must agree with the ones returned from page |
* flip events. With the current vblank helper infrastructure this can |
* be achieved by holding a vblank reference while the page flip is |
* pending, acquired through drm_crtc_vblank_get() and released with |
* drm_crtc_vblank_put(). Drivers are free to implement their own vblank |
* counter and timestamp tracking though, e.g. if they have accurate |
* timestamp registers in hardware. |
* |
* FIXME: |
* |
* Up to that point drivers need to manage events themselves and can use |
* even->base.list freely for that. Specifically they need to ensure |
* that they don't send out page flip (or vblank) events for which the |
* corresponding drm file has been closed already. The drm core |
* unfortunately does not (yet) take care of that. Therefore drivers |
* currently must clean up and release pending events in their |
* ->preclose driver function. |
* |
* This callback is optional. |
* |
* NOTE: |
* |
* Very early versions of the KMS ABI mandated that the driver must |
* block (but not reject) any rendering to the old framebuffer until the |
* flip operation has completed and the old framebuffer is no longer |
* visible. This requirement has been lifted, and userspace is instead |
* expected to request delivery of an event and wait with recycling old |
* buffers until such has been received. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. Note that if a |
* ->page_flip() operation is already pending the callback should return |
* -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode |
* or just runtime disabled through DPMS respectively the new atomic |
* "ACTIVE" state) should result in an -EINVAL error code. Note that |
* drm_atomic_helper_page_flip() checks this already for atomic drivers. |
*/ |
int (*page_flip)(struct drm_crtc *crtc, |
struct drm_framebuffer *fb, |
376,17 → 559,129 |
struct drm_pending_vblank_event *event, |
uint32_t flags); |
/** |
* @set_property: |
* |
* This is the legacy entry point to update a property attached to the |
* CRTC. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_crtc_set_property() to implement this hook. |
* |
* This callback is optional if the driver does not support any legacy |
* driver-private properties. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*set_property)(struct drm_crtc *crtc, |
struct drm_property *property, uint64_t val); |
/* atomic update handling */ |
/** |
* @atomic_duplicate_state: |
* |
* Duplicate the current atomic state for this CRTC and return it. |
* The core and helpers gurantee that any atomic state duplicated with |
* this hook and still owned by the caller (i.e. not transferred to the |
* driver by calling ->atomic_commit() from struct |
* &drm_mode_config_funcs) will be cleaned up by calling the |
* @atomic_destroy_state hook in this structure. |
* |
* Atomic drivers which don't subclass struct &drm_crtc should use |
* drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the |
* state structure to extend it with driver-private state should use |
* __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is |
* duplicated in a consistent fashion across drivers. |
* |
* It is an error to call this hook before crtc->state has been |
* initialized correctly. |
* |
* NOTE: |
* |
* If the duplicate state references refcounted resources this hook must |
* acquire a reference for each of them. The driver must release these |
* references again in @atomic_destroy_state. |
* |
* RETURNS: |
* |
* Duplicated atomic state or NULL when the allocation failed. |
*/ |
struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc); |
/** |
* @atomic_destroy_state: |
* |
* Destroy a state duplicated with @atomic_duplicate_state and release |
* or unreference all resources it references |
*/ |
void (*atomic_destroy_state)(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
/** |
* @atomic_set_property: |
* |
* Decode a driver-private property value and store the decoded value |
* into the passed-in state structure. Since the atomic core decodes all |
* standardized properties (even for extensions beyond the core set of |
* properties which might not be implemented by all drivers) this |
* requires drivers to subclass the state structure. |
* |
* Such driver-private properties should really only be implemented for |
* truly hardware/vendor specific state. Instead it is preferred to |
* standardize atomic extension and decode the properties used to expose |
* such an extension in the core. |
* |
* Do not call this function directly, use |
* drm_atomic_crtc_set_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* NOTE: |
* |
* This function is called in the state assembly phase of atomic |
* modesets, which can be aborted for any reason (including on |
* userspace's request to just check whether a configuration would be |
* possible). Drivers MUST NOT touch any persistent state (hardware or |
* software) or data structures except the passed in @state parameter. |
* |
* Also since userspace controls in which order properties are set this |
* function must not do any input validation (since the state update is |
* incomplete and hence likely inconsistent). Instead any such input |
* validation must be done in the various atomic_check callbacks. |
* |
* RETURNS: |
* |
* 0 if the property has been found, -EINVAL if the property isn't |
* implemented by the driver (which should never happen, the core only |
* asks for properties attached to this CRTC). No other validation is |
* allowed by the driver. The core already checks that the property |
* value is within the range (integer, valid enum value, ...) the driver |
* set when registering the property. |
*/ |
int (*atomic_set_property)(struct drm_crtc *crtc, |
struct drm_crtc_state *state, |
struct drm_property *property, |
uint64_t val); |
/** |
* @atomic_get_property: |
* |
* Reads out the decoded driver-private property. This is used to |
* implement the GETCRTC IOCTL. |
* |
* Do not call this function directly, use |
* drm_atomic_crtc_get_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the property isn't implemented by the |
* driver (which should never happen, the core only asks for |
* properties attached to this CRTC). |
*/ |
int (*atomic_get_property)(struct drm_crtc *crtc, |
const struct drm_crtc_state *state, |
struct drm_property *property, |
416,7 → 711,7 |
* @properties: property tracking for this CRTC |
* @state: current atomic state for this CRTC |
* @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for |
* legacy ioctls |
* legacy IOCTLs |
* |
* Each CRTC may have one or more connectors associated with it. This structure |
* allows the CRTC to be controlled. |
426,6 → 721,8 |
struct device_node *port; |
struct list_head head; |
char *name; |
/* |
* crtc mutex |
* |
463,7 → 760,7 |
uint16_t *gamma_store; |
/* if you are using the helper */ |
const void *helper_private; |
const struct drm_crtc_helper_funcs *helper_private; |
struct drm_object_properties properties; |
470,7 → 767,7 |
struct drm_crtc_state *state; |
/* |
* For legacy crtc ioctls so that atomic drivers can get at the locking |
* For legacy crtc IOCTLs so that atomic drivers can get at the locking |
* acquire context. |
*/ |
struct drm_modeset_acquire_ctx *acquire_ctx; |
495,21 → 792,6 |
/** |
* struct drm_connector_funcs - control connectors on a given device |
* @dpms: set power state |
* @save: save connector state |
* @restore: restore connector state |
* @reset: reset connector after state has been invalidated (e.g. resume) |
* @detect: is this connector active? |
* @fill_modes: fill mode list for this connector |
* @set_property: property for this connector may need an update |
* @destroy: make object go away |
* @force: notify the driver that the connector is forced on |
* @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, |
516,33 → 798,233 |
* etc. |
*/ |
struct drm_connector_funcs { |
/** |
* @dpms: |
* |
* Legacy entry point to set the per-connector DPMS state. Legacy DPMS |
* is exposed as a standard property on the connector, but diverted to |
* this callback in the drm core. Note that atomic drivers don't |
* implement the 4 level DPMS support on the connector any more, but |
* instead only have an on/off "ACTIVE" property on the CRTC object. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_connector_dpms() to implement this hook. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*dpms)(struct drm_connector *connector, int mode); |
void (*save)(struct drm_connector *connector); |
void (*restore)(struct drm_connector *connector); |
/** |
* @reset: |
* |
* Reset connector hardware and software state to off. This function isn't |
* called by the core directly, only through drm_mode_config_reset(). |
* It's not a helper hook only for historical reasons. |
* |
* Atomic drivers can use drm_atomic_helper_connector_reset() to reset |
* atomic state using this hook. |
*/ |
void (*reset)(struct drm_connector *connector); |
/* Check to see if anything is attached to the connector. |
* @force is set to false whilst polling, true when checking the |
* connector due to user request. @force can be used by the driver |
* to avoid expensive, destructive operations during automated |
* probing. |
/** |
* @detect: |
* |
* Check to see if anything is attached to the connector. The parameter |
* force is set to false whilst polling, true when checking the |
* connector due to a user request. force can be used by the driver to |
* avoid expensive, destructive operations during automated probing. |
* |
* FIXME: |
* |
* Note that this hook is only called by the probe helper. It's not in |
* the helper library vtable purely for historical reasons. The only DRM |
* core entry point to probe connector state is @fill_modes. |
* |
* RETURNS: |
* |
* drm_connector_status indicating the connector's status. |
*/ |
enum drm_connector_status (*detect)(struct drm_connector *connector, |
bool force); |
/** |
* @force: |
* |
* This function is called to update internal encoder state when the |
* connector is forced to a certain state by userspace, either through |
* the sysfs interfaces or on the kernel cmdline. In that case the |
* @detect callback isn't called. |
* |
* FIXME: |
* |
* Note that this hook is only called by the probe helper. It's not in |
* the helper library vtable purely for historical reasons. The only DRM |
* core entry point to probe connector state is @fill_modes. |
*/ |
void (*force)(struct drm_connector *connector); |
/** |
* @fill_modes: |
* |
* Entry point for output detection and basic mode validation. The |
* driver should reprobe the output if needed (e.g. when hotplug |
* handling is unreliable), add all detected modes to connector->modes |
* and filter out any the device can't support in any configuration. It |
* also needs to filter out any modes wider or higher than the |
* parameters max_width and max_height indicate. |
* |
* The drivers must also prune any modes no longer valid from |
* connector->modes. Furthermore it must update connector->status and |
* connector->edid. If no EDID has been received for this output |
* connector->edid must be NULL. |
* |
* Drivers using the probe helpers should use |
* drm_helper_probe_single_connector_modes() or |
* drm_helper_probe_single_connector_modes_nomerge() to implement this |
* function. |
* |
* RETURNS: |
* |
* The number of modes detected and filled into connector->modes. |
*/ |
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); |
/** |
* @set_property: |
* |
* This is the legacy entry point to update a property attached to the |
* connector. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_connector_set_property() to implement this hook. |
* |
* This callback is optional if the driver does not support any legacy |
* driver-private properties. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*set_property)(struct drm_connector *connector, struct drm_property *property, |
uint64_t val); |
/** |
* @destroy: |
* |
* Clean up connector resources. This is called at driver unload time |
* through drm_mode_config_cleanup(). It can also be called at runtime |
* when a connector is being hot-unplugged for drivers that support |
* connector hotplugging (e.g. DisplayPort MST). |
*/ |
void (*destroy)(struct drm_connector *connector); |
void (*force)(struct drm_connector *connector); |
/* atomic update handling */ |
/** |
* @atomic_duplicate_state: |
* |
* Duplicate the current atomic state for this connector and return it. |
* The core and helpers gurantee that any atomic state duplicated with |
* this hook and still owned by the caller (i.e. not transferred to the |
* driver by calling ->atomic_commit() from struct |
* &drm_mode_config_funcs) will be cleaned up by calling the |
* @atomic_destroy_state hook in this structure. |
* |
* Atomic drivers which don't subclass struct &drm_connector_state should use |
* drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the |
* state structure to extend it with driver-private state should use |
* __drm_atomic_helper_connector_duplicate_state() to make sure shared state is |
* duplicated in a consistent fashion across drivers. |
* |
* It is an error to call this hook before connector->state has been |
* initialized correctly. |
* |
* NOTE: |
* |
* If the duplicate state references refcounted resources this hook must |
* acquire a reference for each of them. The driver must release these |
* references again in @atomic_destroy_state. |
* |
* RETURNS: |
* |
* Duplicated atomic state or NULL when the allocation failed. |
*/ |
struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector); |
/** |
* @atomic_destroy_state: |
* |
* Destroy a state duplicated with @atomic_duplicate_state and release |
* or unreference all resources it references |
*/ |
void (*atomic_destroy_state)(struct drm_connector *connector, |
struct drm_connector_state *state); |
/** |
* @atomic_set_property: |
* |
* Decode a driver-private property value and store the decoded value |
* into the passed-in state structure. Since the atomic core decodes all |
* standardized properties (even for extensions beyond the core set of |
* properties which might not be implemented by all drivers) this |
* requires drivers to subclass the state structure. |
* |
* Such driver-private properties should really only be implemented for |
* truly hardware/vendor specific state. Instead it is preferred to |
* standardize atomic extension and decode the properties used to expose |
* such an extension in the core. |
* |
* Do not call this function directly, use |
* drm_atomic_connector_set_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* NOTE: |
* |
* This function is called in the state assembly phase of atomic |
* modesets, which can be aborted for any reason (including on |
* userspace's request to just check whether a configuration would be |
* possible). Drivers MUST NOT touch any persistent state (hardware or |
* software) or data structures except the passed in @state parameter. |
* |
* Also since userspace controls in which order properties are set this |
* function must not do any input validation (since the state update is |
* incomplete and hence likely inconsistent). Instead any such input |
* validation must be done in the various atomic_check callbacks. |
* |
* RETURNS: |
* |
* 0 if the property has been found, -EINVAL if the property isn't |
* implemented by the driver (which shouldn't ever happen, the core only |
* asks for properties attached to this connector). No other validation |
* is allowed by the driver. The core already checks that the property |
* value is within the range (integer, valid enum value, ...) the driver |
* set when registering the property. |
*/ |
int (*atomic_set_property)(struct drm_connector *connector, |
struct drm_connector_state *state, |
struct drm_property *property, |
uint64_t val); |
/** |
* @atomic_get_property: |
* |
* Reads out the decoded driver-private property. This is used to |
* implement the GETCONNECTOR IOCTL. |
* |
* Do not call this function directly, use |
* drm_atomic_connector_get_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the property isn't implemented by the |
* driver (which shouldn't ever happen, the core only asks for |
* properties attached to this connector). |
*/ |
int (*atomic_get_property)(struct drm_connector *connector, |
const struct drm_connector_state *state, |
struct drm_property *property, |
551,13 → 1033,26 |
/** |
* struct drm_encoder_funcs - encoder controls |
* @reset: reset state (e.g. at init or resume time) |
* @destroy: cleanup and free associated data |
* |
* Encoders sit between CRTCs and connectors. |
*/ |
struct drm_encoder_funcs { |
/** |
* @reset: |
* |
* Reset encoder hardware and software state to off. This function isn't |
* called by the core directly, only through drm_mode_config_reset(). |
* It's not a helper hook only for historical reasons. |
*/ |
void (*reset)(struct drm_encoder *encoder); |
/** |
* @destroy: |
* |
* Clean up encoder resources. This is only called at driver unload time |
* through drm_mode_config_cleanup() since an encoder cannot be |
* hotplugged in DRM. |
*/ |
void (*destroy)(struct drm_encoder *encoder); |
}; |
593,7 → 1088,7 |
struct drm_crtc *crtc; |
struct drm_bridge *bridge; |
const struct drm_encoder_funcs *funcs; |
const void *helper_private; |
const struct drm_encoder_helper_funcs *helper_private; |
}; |
/* should we poll this connector for connects and disconnects */ |
671,6 → 1166,7 |
struct drm_mode_object base; |
char *name; |
int connector_id; |
int connector_type; |
int connector_type_id; |
bool interlace_allowed; |
698,7 → 1194,7 |
/* requested DPMS state */ |
int dpms; |
const void *helper_private; |
const struct drm_connector_helper_funcs *helper_private; |
/* forced on connector */ |
struct drm_cmdline_mode cmdline_mode; |
778,19 → 1274,34 |
/** |
* struct drm_plane_funcs - driver plane control functions |
* @update_plane: update the plane configuration |
* @disable_plane: shut down the plane |
* @destroy: clean up plane resources |
* @reset: reset plane after state has been invalidated (e.g. resume) |
* @set_property: called when a property is changed |
* @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 { |
/** |
* @update_plane: |
* |
* This is the legacy entry point to enable and configure the plane for |
* the given CRTC and framebuffer. It is never called to disable the |
* plane, i.e. the passed-in crtc and fb paramters are never NULL. |
* |
* The source rectangle in frame buffer memory coordinates is given by |
* the src_x, src_y, src_w and src_h parameters (as 16.16 fixed point |
* values). Devices that don't support subpixel plane coordinates can |
* ignore the fractional part. |
* |
* The destination rectangle in CRTC coordinates is given by the |
* crtc_x, crtc_y, crtc_w and crtc_h parameters (as integer values). |
* Devices scale the source rectangle to the destination rectangle. If |
* scaling is not supported, and the source rectangle size doesn't match |
* the destination rectangle size, the driver must return a |
* -<errorname>EINVAL</errorname> error. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_update_plane() to implement this hook. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*update_plane)(struct drm_plane *plane, |
struct drm_crtc *crtc, struct drm_framebuffer *fb, |
int crtc_x, int crtc_y, |
797,21 → 1308,169 |
unsigned int crtc_w, unsigned int crtc_h, |
uint32_t src_x, uint32_t src_y, |
uint32_t src_w, uint32_t src_h); |
/** |
* @disable_plane: |
* |
* This is the legacy entry point to disable the plane. The DRM core |
* calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call |
* with the frame buffer ID set to 0. Disabled planes must not be |
* processed by the CRTC. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_disable_plane() to implement this hook. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*disable_plane)(struct drm_plane *plane); |
/** |
* @destroy: |
* |
* Clean up plane resources. This is only called at driver unload time |
* through drm_mode_config_cleanup() since a plane cannot be hotplugged |
* in DRM. |
*/ |
void (*destroy)(struct drm_plane *plane); |
/** |
* @reset: |
* |
* Reset plane hardware and software state to off. This function isn't |
* called by the core directly, only through drm_mode_config_reset(). |
* It's not a helper hook only for historical reasons. |
* |
* Atomic drivers can use drm_atomic_helper_plane_reset() to reset |
* atomic state using this hook. |
*/ |
void (*reset)(struct drm_plane *plane); |
/** |
* @set_property: |
* |
* This is the legacy entry point to update a property attached to the |
* plane. |
* |
* Drivers implementing atomic modeset should use |
* drm_atomic_helper_plane_set_property() to implement this hook. |
* |
* This callback is optional if the driver does not support any legacy |
* driver-private properties. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*set_property)(struct drm_plane *plane, |
struct drm_property *property, uint64_t val); |
/* atomic update handling */ |
/** |
* @atomic_duplicate_state: |
* |
* Duplicate the current atomic state for this plane and return it. |
* The core and helpers gurantee that any atomic state duplicated with |
* this hook and still owned by the caller (i.e. not transferred to the |
* driver by calling ->atomic_commit() from struct |
* &drm_mode_config_funcs) will be cleaned up by calling the |
* @atomic_destroy_state hook in this structure. |
* |
* Atomic drivers which don't subclass struct &drm_plane_state should use |
* drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the |
* state structure to extend it with driver-private state should use |
* __drm_atomic_helper_plane_duplicate_state() to make sure shared state is |
* duplicated in a consistent fashion across drivers. |
* |
* It is an error to call this hook before plane->state has been |
* initialized correctly. |
* |
* NOTE: |
* |
* If the duplicate state references refcounted resources this hook must |
* acquire a reference for each of them. The driver must release these |
* references again in @atomic_destroy_state. |
* |
* RETURNS: |
* |
* Duplicated atomic state or NULL when the allocation failed. |
*/ |
struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane); |
/** |
* @atomic_destroy_state: |
* |
* Destroy a state duplicated with @atomic_duplicate_state and release |
* or unreference all resources it references |
*/ |
void (*atomic_destroy_state)(struct drm_plane *plane, |
struct drm_plane_state *state); |
/** |
* @atomic_set_property: |
* |
* Decode a driver-private property value and store the decoded value |
* into the passed-in state structure. Since the atomic core decodes all |
* standardized properties (even for extensions beyond the core set of |
* properties which might not be implemented by all drivers) this |
* requires drivers to subclass the state structure. |
* |
* Such driver-private properties should really only be implemented for |
* truly hardware/vendor specific state. Instead it is preferred to |
* standardize atomic extension and decode the properties used to expose |
* such an extension in the core. |
* |
* Do not call this function directly, use |
* drm_atomic_plane_set_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* NOTE: |
* |
* This function is called in the state assembly phase of atomic |
* modesets, which can be aborted for any reason (including on |
* userspace's request to just check whether a configuration would be |
* possible). Drivers MUST NOT touch any persistent state (hardware or |
* software) or data structures except the passed in @state parameter. |
* |
* Also since userspace controls in which order properties are set this |
* function must not do any input validation (since the state update is |
* incomplete and hence likely inconsistent). Instead any such input |
* validation must be done in the various atomic_check callbacks. |
* |
* RETURNS: |
* |
* 0 if the property has been found, -EINVAL if the property isn't |
* implemented by the driver (which shouldn't ever happen, the core only |
* asks for properties attached to this plane). No other validation is |
* allowed by the driver. The core already checks that the property |
* value is within the range (integer, valid enum value, ...) the driver |
* set when registering the property. |
*/ |
int (*atomic_set_property)(struct drm_plane *plane, |
struct drm_plane_state *state, |
struct drm_property *property, |
uint64_t val); |
/** |
* @atomic_get_property: |
* |
* Reads out the decoded driver-private property. This is used to |
* implement the GETPLANE IOCTL. |
* |
* Do not call this function directly, use |
* drm_atomic_plane_get_property() instead. |
* |
* This callback is optional if the driver does not support any |
* driver-private atomic properties. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the property isn't implemented by the |
* driver (which should never happen, the core only asks for |
* properties attached to this plane). |
*/ |
int (*atomic_get_property)(struct drm_plane *plane, |
const struct drm_plane_state *state, |
struct drm_property *property, |
824,6 → 1483,7 |
DRM_PLANE_TYPE_CURSOR, |
}; |
/** |
* struct drm_plane - central DRM plane control structure |
* @dev: DRM device this plane belongs to |
846,6 → 1506,8 |
struct drm_device *dev; |
struct list_head head; |
char *name; |
struct drm_modeset_lock mutex; |
struct drm_mode_object base; |
866,7 → 1528,7 |
enum drm_plane_type type; |
const void *helper_private; |
const struct drm_plane_helper_funcs *helper_private; |
struct drm_plane_state *state; |
}; |
874,24 → 1536,114 |
/** |
* 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 |
* @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 |
*/ |
struct drm_bridge_funcs { |
int (*attach)(struct drm_bridge *bridge); |
/** |
* @mode_fixup: |
* |
* This callback is used to validate and adjust a mode. The paramater |
* mode is the display mode that should be fed to the next element in |
* the display chain, either the final &drm_connector or the next |
* &drm_bridge. The parameter adjusted_mode is the input mode the bridge |
* requires. It can be modified by this callback and does not need to |
* match mode. |
* |
* This is the only hook that allows a bridge to reject a modeset. If |
* this function passes all other callbacks must succeed for this |
* configuration. |
* |
* NOTE: |
* |
* This function is called in the check phase of atomic modesets, which |
* can be aborted for any reason (including on userspace's request to |
* just check whether a configuration would be possible). Drivers MUST |
* NOT touch any persistent state (hardware or software) or data |
* structures except the passed in @state parameter. |
* |
* RETURNS: |
* |
* True if an acceptable configuration is possible, false if the modeset |
* operation should be rejected. |
*/ |
bool (*mode_fixup)(struct drm_bridge *bridge, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/** |
* @disable: |
* |
* This callback should disable the bridge. It is called right before |
* the preceding element in the display pipe is disabled. If the |
* preceding element is a bridge this means it's called before that |
* bridge's ->disable() function. If the preceding element is a |
* &drm_encoder it's called right before the encoder's ->disable(), |
* ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. |
* |
* The bridge can assume that the display pipe (i.e. clocks and timing |
* signals) feeding it is still running when this callback is called. |
*/ |
void (*disable)(struct drm_bridge *bridge); |
/** |
* @post_disable: |
* |
* This callback should disable the bridge. It is called right after |
* the preceding element in the display pipe is disabled. If the |
* preceding element is a bridge this means it's called after that |
* bridge's ->post_disable() function. If the preceding element is a |
* &drm_encoder it's called right after the encoder's ->disable(), |
* ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs. |
* |
* The bridge must assume that the display pipe (i.e. clocks and timing |
* singals) feeding it is no longer running when this callback is |
* called. |
*/ |
void (*post_disable)(struct drm_bridge *bridge); |
/** |
* @mode_set: |
* |
* This callback should set the given mode on the bridge. It is called |
* after the ->mode_set() callback for the preceding element in the |
* display pipeline has been called already. The display pipe (i.e. |
* clocks and timing signals) is off when this function is called. |
*/ |
void (*mode_set)(struct drm_bridge *bridge, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/** |
* @pre_enable: |
* |
* This callback should enable the bridge. It is called right before |
* the preceding element in the display pipe is enabled. If the |
* preceding element is a bridge this means it's called before that |
* bridge's ->pre_enable() function. If the preceding element is a |
* &drm_encoder it's called right before the encoder's ->enable(), |
* ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. |
* |
* The display pipe (i.e. clocks and timing signals) feeding this bridge |
* will not yet be running when this callback is called. The bridge must |
* not enable the display link feeding the next bridge in the chain (if |
* there is one) when this callback is called. |
*/ |
void (*pre_enable)(struct drm_bridge *bridge); |
/** |
* @enable: |
* |
* This callback should enable the bridge. It is called right after |
* the preceding element in the display pipe is enabled. If the |
* preceding element is a bridge this means it's called after that |
* bridge's ->enable() function. If the preceding element is a |
* &drm_encoder it's called right after the encoder's ->enable(), |
* ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs. |
* |
* The bridge can assume that the display pipe (i.e. clocks and timing |
* signals) feeding it is running when this callback is called. This |
* callback must enable the display link feeding the next bridge in the |
* chain if there is one. |
*/ |
void (*enable)(struct drm_bridge *bridge); |
}; |
922,7 → 1674,7 |
* struct drm_atomic_state - the global state object for atomic updates |
* @dev: parent DRM device |
* @allow_modeset: allow full modeset |
* @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics |
* @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 |
977,31 → 1729,265 |
/** |
* 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 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. |
*/ |
struct drm_mode_config_funcs { |
/** |
* @fb_create: |
* |
* Create a new framebuffer object. The core does basic checks on the |
* requested metadata, but most of that is left to the driver. See |
* struct &drm_mode_fb_cmd2 for details. |
* |
* If the parameters are deemed valid and the backing storage objects in |
* the underlying memory manager all exist, then the driver allocates |
* a new &drm_framebuffer structure, subclassed to contain |
* driver-specific information (like the internal native buffer object |
* references). It also needs to fill out all relevant metadata, which |
* should be done by calling drm_helper_mode_fill_fb_struct(). |
* |
* The initialization is finalized by calling drm_framebuffer_init(), |
* which registers the framebuffer and makes it accessible to other |
* threads. |
* |
* RETURNS: |
* |
* A new framebuffer with an initial reference count of 1 or a negative |
* error code encoded with ERR_PTR(). |
*/ |
struct drm_framebuffer *(*fb_create)(struct drm_device *dev, |
struct drm_file *file_priv, |
struct drm_mode_fb_cmd2 *mode_cmd); |
const struct drm_mode_fb_cmd2 *mode_cmd); |
/** |
* @output_poll_changed: |
* |
* Callback used by helpers to inform the driver of output configuration |
* changes. |
* |
* Drivers implementing fbdev emulation with the helpers can call |
* drm_fb_helper_hotplug_changed from this hook to inform the fbdev |
* helper of output changes. |
* |
* FIXME: |
* |
* Except that there's no vtable for device-level helper callbacks |
* there's no reason this is a core function. |
*/ |
void (*output_poll_changed)(struct drm_device *dev); |
/** |
* @atomic_check: |
* |
* This is the only hook to validate an atomic modeset update. This |
* function must reject any modeset and state changes which the hardware |
* or driver doesn't support. This includes but is of course not limited |
* to: |
* |
* - Checking that the modes, framebuffers, scaling and placement |
* requirements and so on are within the limits of the hardware. |
* |
* - Checking that any hidden shared resources are not oversubscribed. |
* This can be shared PLLs, shared lanes, overall memory bandwidth, |
* display fifo space (where shared between planes or maybe even |
* CRTCs). |
* |
* - Checking that virtualized resources exported to userspace are not |
* oversubscribed. For various reasons it can make sense to expose |
* more planes, crtcs or encoders than which are physically there. One |
* example is dual-pipe operations (which generally should be hidden |
* from userspace if when lockstepped in hardware, exposed otherwise), |
* where a plane might need 1 hardware plane (if it's just on one |
* pipe), 2 hardware planes (when it spans both pipes) or maybe even |
* shared a hardware plane with a 2nd plane (if there's a compatible |
* plane requested on the area handled by the other pipe). |
* |
* - Check that any transitional state is possible and that if |
* requested, the update can indeed be done in the vblank period |
* without temporarily disabling some functions. |
* |
* - Check any other constraints the driver or hardware might have. |
* |
* - This callback also needs to correctly fill out the &drm_crtc_state |
* in this update to make sure that drm_atomic_crtc_needs_modeset() |
* reflects the nature of the possible update and returns true if and |
* only if the update cannot be applied without tearing within one |
* vblank on that CRTC. The core uses that information to reject |
* updates which require a full modeset (i.e. blanking the screen, or |
* at least pausing updates for a substantial amount of time) if |
* userspace has disallowed that in its request. |
* |
* - The driver also does not need to repeat basic input validation |
* like done for the corresponding legacy entry points. The core does |
* that before calling this hook. |
* |
* See the documentation of @atomic_commit for an exhaustive list of |
* error conditions which don't have to be checked at the |
* ->atomic_check() stage? |
* |
* See the documentation for struct &drm_atomic_state for how exactly |
* an atomic modeset update is described. |
* |
* Drivers using the atomic helpers can implement this hook using |
* drm_atomic_helper_check(), or one of the exported sub-functions of |
* it. |
* |
* RETURNS: |
* |
* 0 on success or one of the below negative error codes: |
* |
* - -EINVAL, if any of the above constraints are violated. |
* |
* - -EDEADLK, when returned from an attempt to acquire an additional |
* &drm_modeset_lock through drm_modeset_lock(). |
* |
* - -ENOMEM, if allocating additional state sub-structures failed due |
* to lack of memory. |
* |
* - -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. |
* This can either be due to a pending signal, or because the driver |
* needs to completely bail out to recover from an exceptional |
* situation like a GPU hang. From a userspace point all errors are |
* treated equally. |
*/ |
int (*atomic_check)(struct drm_device *dev, |
struct drm_atomic_state *a); |
struct drm_atomic_state *state); |
/** |
* @atomic_commit: |
* |
* This is the only hook to commit an atomic modeset update. The core |
* guarantees that @atomic_check has been called successfully before |
* calling this function, and that nothing has been changed in the |
* interim. |
* |
* See the documentation for struct &drm_atomic_state for how exactly |
* an atomic modeset update is described. |
* |
* Drivers using the atomic helpers can implement this hook using |
* drm_atomic_helper_commit(), or one of the exported sub-functions of |
* it. |
* |
* Asynchronous commits (as indicated with the async parameter) must |
* do any preparatory work which might result in an unsuccessful commit |
* in the context of this callback. The only exceptions are hardware |
* errors resulting in -EIO. But even in that case the driver must |
* ensure that the display pipe is at least running, to avoid |
* compositors crashing when pageflips don't work. Anything else, |
* specifically committing the update to the hardware, should be done |
* without blocking the caller. For updates which do not require a |
* modeset this must be guaranteed. |
* |
* The driver must wait for any pending rendering to the new |
* framebuffers to complete before executing the flip. It should also |
* wait for any pending rendering from other drivers if the underlying |
* buffer is a shared dma-buf. Asynchronous commits must not wait for |
* rendering in the context of this callback. |
* |
* An application can request to be notified when the atomic commit has |
* completed. These events are per-CRTC and can be distinguished by the |
* CRTC index supplied in &drm_event to userspace. |
* |
* The drm core will supply a struct &drm_event in the event |
* member of each CRTC's &drm_crtc_state structure. This can be handled by the |
* drm_crtc_send_vblank_event() function, which the driver should call on |
* the provided event upon completion of the atomic commit. Note that if |
* the driver supports vblank signalling and timestamping the vblank |
* counters and timestamps must agree with the ones returned from page |
* flip events. With the current vblank helper infrastructure this can |
* be achieved by holding a vblank reference while the page flip is |
* pending, acquired through drm_crtc_vblank_get() and released with |
* drm_crtc_vblank_put(). Drivers are free to implement their own vblank |
* counter and timestamp tracking though, e.g. if they have accurate |
* timestamp registers in hardware. |
* |
* NOTE: |
* |
* Drivers are not allowed to shut down any display pipe successfully |
* enabled through an atomic commit on their own. Doing so can result in |
* compositors crashing if a page flip is suddenly rejected because the |
* pipe is off. |
* |
* RETURNS: |
* |
* 0 on success or one of the below negative error codes: |
* |
* - -EBUSY, if an asynchronous updated is requested and there is |
* an earlier updated pending. Drivers are allowed to support a queue |
* of outstanding updates, but currently no driver supports that. |
* Note that drivers must wait for preceding updates to complete if a |
* synchronous update is requested, they are not allowed to fail the |
* commit in that case. |
* |
* - -ENOMEM, if the driver failed to allocate memory. Specifically |
* this can happen when trying to pin framebuffers, which must only |
* be done when committing the state. |
* |
* - -ENOSPC, as a refinement of the more generic -ENOMEM to indicate |
* that the driver has run out of vram, iommu space or similar GPU |
* address space needed for framebuffer. |
* |
* - -EIO, if the hardware completely died. |
* |
* - -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. |
* This can either be due to a pending signal, or because the driver |
* needs to completely bail out to recover from an exceptional |
* situation like a GPU hang. From a userspace point of view all errors are |
* treated equally. |
* |
* This list is exhaustive. Specifically this hook is not allowed to |
* return -EINVAL (any invalid requests should be caught in |
* @atomic_check) or -EDEADLK (this function must not acquire |
* additional modeset locks). |
*/ |
int (*atomic_commit)(struct drm_device *dev, |
struct drm_atomic_state *a, |
struct drm_atomic_state *state, |
bool async); |
/** |
* @atomic_state_alloc: |
* |
* This optional hook can be used by drivers that want to subclass struct |
* &drm_atomic_state to be able to track their own driver-private global |
* state easily. If this hook is implemented, drivers must also |
* implement @atomic_state_clear and @atomic_state_free. |
* |
* RETURNS: |
* |
* A new &drm_atomic_state on success or NULL on failure. |
*/ |
struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev); |
/** |
* @atomic_state_clear: |
* |
* This hook must clear any driver private state duplicated into the |
* passed-in &drm_atomic_state. This hook is called when the caller |
* encountered a &drm_modeset_lock deadlock and needs to drop all |
* already acquired locks as part of the deadlock avoidance dance |
* implemented in drm_modeset_lock_backoff(). |
* |
* Any duplicated state must be invalidated since a concurrent atomic |
* update might change it, and the drm atomic interfaces always apply |
* updates as relative changes to the current state. |
* |
* Drivers that implement this must call drm_atomic_state_default_clear() |
* to clear common state. |
*/ |
void (*atomic_state_clear)(struct drm_atomic_state *state); |
/** |
* @atomic_state_free: |
* |
* This hook needs driver private resources and the &drm_atomic_state |
* itself. Note that the core first calls drm_atomic_state_clear() to |
* avoid code duplicate between the clear and free hooks. |
* |
* Drivers that implement this must call drm_atomic_state_default_free() |
* to release common resources. |
*/ |
void (*atomic_state_free)(struct drm_atomic_state *state); |
}; |
1010,7 → 1996,7 |
* @mutex: mutex protecting KMS related lists and structures |
* @connection_mutex: ww mutex protecting connector state and routing |
* @acquire_ctx: global implicit acquire context used by atomic drivers for |
* legacy ioctls |
* legacy IOCTLs |
* @idr_mutex: mutex for KMS ID allocation and management |
* @crtc_idr: main KMS ID tracking object |
* @fb_lock: mutex to protect fb state and lists |
1062,6 → 2048,7 |
struct list_head fb_list; |
int num_connector; |
struct ida connector_ida; |
struct list_head connector_list; |
int num_encoder; |
struct list_head encoder_list; |
1166,7 → 2153,7 |
*/ |
#define drm_for_each_plane_mask(plane, dev, plane_mask) \ |
list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ |
if ((plane_mask) & (1 << drm_plane_index(plane))) |
for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) |
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base) |
1183,11 → 2170,13 |
char *name; |
}; |
extern int drm_crtc_init_with_planes(struct drm_device *dev, |
extern __printf(6, 7) |
int drm_crtc_init_with_planes(struct drm_device *dev, |
struct drm_crtc *crtc, |
struct drm_plane *primary, |
struct drm_plane *cursor, |
const struct drm_crtc_funcs *funcs); |
const struct drm_crtc_funcs *funcs, |
const char *name, ...); |
extern void drm_crtc_cleanup(struct drm_crtc *crtc); |
extern unsigned int drm_crtc_index(struct drm_crtc *crtc); |
1213,7 → 2202,11 |
void drm_connector_unregister(struct drm_connector *connector); |
extern void drm_connector_cleanup(struct drm_connector *connector); |
extern unsigned int drm_connector_index(struct drm_connector *connector); |
static inline unsigned drm_connector_index(struct drm_connector *connector) |
{ |
return connector->connector_id; |
} |
/* helper to unplug all connectors from sysfs for device */ |
extern void drm_connector_unplug_all(struct drm_device *dev); |
1233,10 → 2226,11 |
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, |
extern __printf(5, 6) |
int drm_encoder_init(struct drm_device *dev, |
struct drm_encoder *encoder, |
const struct drm_encoder_funcs *funcs, |
int encoder_type); |
int encoder_type, const char *name, ...); |
/** |
* drm_encoder_crtc_ok - can a given crtc drive a given encoder? |
1251,13 → 2245,15 |
return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); |
} |
extern int drm_universal_plane_init(struct drm_device *dev, |
extern __printf(8, 9) |
int drm_universal_plane_init(struct drm_device *dev, |
struct drm_plane *plane, |
unsigned long possible_crtcs, |
const struct drm_plane_funcs *funcs, |
const uint32_t *formats, |
unsigned int format_count, |
enum drm_plane_type type); |
enum drm_plane_type type, |
const char *name, ...); |
extern int drm_plane_init(struct drm_device *dev, |
struct drm_plane *plane, |
unsigned long possible_crtcs, |
1543,7 → 2539,7 |
/* 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) |
for_each_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) |
/drivers/include/drm/drm_crtc_helper.h |
---|
40,149 → 40,8 |
#include <linux/fb.h> |
#include <drm/drm_crtc.h> |
#include <drm/drm_modeset_helper_vtables.h> |
enum mode_set_atomic { |
LEAVE_ATOMIC_MODE_SET, |
ENTER_ATOMIC_MODE_SET, |
}; |
/** |
* 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 { |
/* |
* Control power levels on the CRTC. If the mode passed in is |
* unsupported, the provider must use the next lowest power level. |
*/ |
void (*dpms)(struct drm_crtc *crtc, int mode); |
void (*prepare)(struct drm_crtc *crtc); |
void (*commit)(struct drm_crtc *crtc); |
/* Provider can fixup or change mode timings before modeset occurs */ |
bool (*mode_fixup)(struct drm_crtc *crtc, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/* Actually set the mode */ |
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* */ |
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, |
struct drm_framebuffer *old_fb); |
int (*mode_set_base_atomic)(struct drm_crtc *crtc, |
struct drm_framebuffer *fb, int x, int y, |
enum mode_set_atomic); |
/* reload the current crtc LUT */ |
void (*load_lut)(struct drm_crtc *crtc); |
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, |
struct drm_crtc_state *old_crtc_state); |
void (*atomic_flush)(struct drm_crtc *crtc, |
struct drm_crtc_state *old_crtc_state); |
}; |
/** |
* 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 |
* @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); |
void (*save)(struct drm_encoder *encoder); |
void (*restore)(struct drm_encoder *encoder); |
bool (*mode_fixup)(struct drm_encoder *encoder, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
void (*prepare)(struct drm_encoder *encoder); |
void (*commit)(struct drm_encoder *encoder); |
void (*mode_set)(struct drm_encoder *encoder, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); |
/* detect for DAC style encoders */ |
enum drm_connector_status (*detect)(struct drm_encoder *encoder, |
struct drm_connector *connector); |
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); |
}; |
/** |
* struct drm_connector_helper_funcs - helper operations for connectors |
* @get_modes: get mode list for this 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. |
*/ |
struct drm_connector_helper_funcs { |
int (*get_modes)(struct drm_connector *connector); |
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); |
extern int drm_crtc_helper_set_config(struct drm_mode_set *set); |
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, |
197,26 → 56,8 |
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *); |
extern void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, |
struct drm_mode_fb_cmd2 *mode_cmd); |
const struct drm_mode_fb_cmd2 *mode_cmd); |
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, |
const struct drm_crtc_helper_funcs *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 = funcs; |
} |
static inline void drm_connector_helper_add(struct drm_connector *connector, |
const struct drm_connector_helper_funcs *funcs) |
{ |
connector->helper_private = funcs; |
} |
extern void drm_helper_resume_force_mode(struct drm_device *dev); |
int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, |
229,10 → 70,6 |
extern int drm_helper_probe_single_connector_modes(struct drm_connector |
*connector, uint32_t maxX, |
uint32_t maxY); |
extern int drm_helper_probe_single_connector_modes_nomerge(struct drm_connector |
*connector, |
uint32_t maxX, |
uint32_t maxY); |
extern void drm_kms_helper_poll_init(struct drm_device *dev); |
extern void drm_kms_helper_poll_fini(struct drm_device *dev); |
extern bool drm_helper_hpd_irq_event(struct drm_device *dev); |
/drivers/include/drm/drm_dp_helper.h |
---|
455,16 → 455,52 |
# define DP_EDP_14 0x03 |
#define DP_EDP_GENERAL_CAP_1 0x701 |
# define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP (1 << 0) |
# define DP_EDP_BACKLIGHT_PIN_ENABLE_CAP (1 << 1) |
# define DP_EDP_BACKLIGHT_AUX_ENABLE_CAP (1 << 2) |
# define DP_EDP_PANEL_SELF_TEST_PIN_ENABLE_CAP (1 << 3) |
# define DP_EDP_PANEL_SELF_TEST_AUX_ENABLE_CAP (1 << 4) |
# define DP_EDP_FRC_ENABLE_CAP (1 << 5) |
# define DP_EDP_COLOR_ENGINE_CAP (1 << 6) |
# define DP_EDP_SET_POWER_CAP (1 << 7) |
#define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP 0x702 |
# define DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP (1 << 0) |
# define DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP (1 << 1) |
# define DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT (1 << 2) |
# define DP_EDP_BACKLIGHT_AUX_PWM_PRODUCT_CAP (1 << 3) |
# define DP_EDP_BACKLIGHT_FREQ_PWM_PIN_PASSTHRU_CAP (1 << 4) |
# define DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP (1 << 5) |
# define DP_EDP_DYNAMIC_BACKLIGHT_CAP (1 << 6) |
# define DP_EDP_VBLANK_BACKLIGHT_UPDATE_CAP (1 << 7) |
#define DP_EDP_GENERAL_CAP_2 0x703 |
# define DP_EDP_OVERDRIVE_ENGINE_ENABLED (1 << 0) |
#define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */ |
# define DP_EDP_X_REGION_CAP_MASK (0xf << 0) |
# define DP_EDP_X_REGION_CAP_SHIFT 0 |
# define DP_EDP_Y_REGION_CAP_MASK (0xf << 4) |
# define DP_EDP_Y_REGION_CAP_SHIFT 4 |
#define DP_EDP_DISPLAY_CONTROL_REGISTER 0x720 |
# define DP_EDP_BACKLIGHT_ENABLE (1 << 0) |
# define DP_EDP_BLACK_VIDEO_ENABLE (1 << 1) |
# define DP_EDP_FRC_ENABLE (1 << 2) |
# define DP_EDP_COLOR_ENGINE_ENABLE (1 << 3) |
# define DP_EDP_VBLANK_BACKLIGHT_UPDATE_ENABLE (1 << 7) |
#define DP_EDP_BACKLIGHT_MODE_SET_REGISTER 0x721 |
# define DP_EDP_BACKLIGHT_CONTROL_MODE_MASK (3 << 0) |
# define DP_EDP_BACKLIGHT_CONTROL_MODE_PWM (0 << 0) |
# define DP_EDP_BACKLIGHT_CONTROL_MODE_PRESET (1 << 0) |
# define DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD (2 << 0) |
# define DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT (3 << 0) |
# define DP_EDP_BACKLIGHT_FREQ_PWM_PIN_PASSTHRU_ENABLE (1 << 2) |
# define DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE (1 << 3) |
# define DP_EDP_DYNAMIC_BACKLIGHT_ENABLE (1 << 4) |
# define DP_EDP_REGIONAL_BACKLIGHT_ENABLE (1 << 5) |
# define DP_EDP_UPDATE_REGION_BRIGHTNESS (1 << 6) /* eDP 1.4 */ |
#define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722 |
#define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723 |
/drivers/include/drm/drm_dp_mst_helper.h |
---|
88,6 → 88,7 |
struct drm_dp_mst_topology_mgr *mgr; |
struct edid *cached_edid; /* for DP logical ports - make tiling work */ |
bool has_audio; |
}; |
/** |
214,13 → 215,13 |
struct drm_dp_sideband_msg_hdr initial_hdr; |
}; |
#define DRM_DP_MAX_SDP_STREAMS 16 |
struct drm_dp_allocate_payload { |
u8 port_number; |
u8 number_sdp_streams; |
u8 vcpi; |
u16 pbn; |
u8 sdp_stream_sink[8]; |
u8 sdp_stream_sink[DRM_DP_MAX_SDP_STREAMS]; |
}; |
struct drm_dp_allocate_payload_ack_reply { |
417,7 → 418,7 |
struct drm_dp_mst_topology_mgr { |
struct device *dev; |
struct drm_dp_mst_topology_cbs *cbs; |
const struct drm_dp_mst_topology_cbs *cbs; |
int max_dpcd_transaction_bytes; |
struct drm_dp_aux *aux; /* auxch for this topology mgr to use */ |
int max_payloads; |
477,6 → 478,8 |
enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); |
bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, |
struct drm_dp_mst_port *port); |
struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); |
/drivers/include/drm/drm_fb_helper.h |
---|
34,6 → 34,11 |
#include <linux/kgdb.h> |
enum mode_set_atomic { |
LEAVE_ATOMIC_MODE_SET, |
ENTER_ATOMIC_MODE_SET, |
}; |
struct drm_fb_offset { |
int x, y; |
}; |
74,25 → 79,76 |
/** |
* struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library |
* @gamma_set: Set the given gamma lut register on the given crtc. |
* @gamma_get: Read the given gamma lut register on the given crtc, used to |
* save the current lut when force-restoring the fbdev for e.g. |
* kdbg. |
* @fb_probe: Driver callback to allocate and initialize the fbdev info |
* structure. Furthermore it also needs to allocate the drm |
* framebuffer used to back the fbdev. |
* @initial_config: Setup an initial fbdev display configuration |
* |
* Driver callbacks used by the fbdev emulation helper library. |
*/ |
struct drm_fb_helper_funcs { |
/** |
* @gamma_set: |
* |
* Set the given gamma LUT register on the given CRTC. |
* |
* This callback is optional. |
* |
* FIXME: |
* |
* This callback is functionally redundant with the core gamma table |
* support and simply exists because the fbdev hasn't yet been |
* refactored to use the core gamma table interfaces. |
*/ |
void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, |
u16 blue, int regno); |
/** |
* @gamma_get: |
* |
* Read the given gamma LUT register on the given CRTC, used to save the |
* current LUT when force-restoring the fbdev for e.g. kdbg. |
* |
* This callback is optional. |
* |
* FIXME: |
* |
* This callback is functionally redundant with the core gamma table |
* support and simply exists because the fbdev hasn't yet been |
* refactored to use the core gamma table interfaces. |
*/ |
void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green, |
u16 *blue, int regno); |
/** |
* @fb_probe: |
* |
* Driver callback to allocate and initialize the fbdev info structure. |
* Furthermore it also needs to allocate the DRM framebuffer used to |
* back the fbdev. |
* |
* This callback is mandatory. |
* |
* RETURNS: |
* |
* The driver should return 0 on success and a negative error code on |
* failure. |
*/ |
int (*fb_probe)(struct drm_fb_helper *helper, |
struct drm_fb_helper_surface_size *sizes); |
/** |
* @initial_config: |
* |
* Driver callback to setup an initial fbdev display configuration. |
* Drivers can use this callback to tell the fbdev emulation what the |
* preferred initial configuration is. This is useful to implement |
* smooth booting where the fbdev (and subsequently all userspace) never |
* changes the mode, but always inherits the existing configuration. |
* |
* This callback is optional. |
* |
* RETURNS: |
* |
* The driver should return true if a suitable initial configuration has |
* been filled out and false when the fbdev helper should fall back to |
* the default probing logic. |
*/ |
bool (*initial_config)(struct drm_fb_helper *fb_helper, |
struct drm_fb_helper_crtc **crtcs, |
struct drm_display_mode **modes, |
105,7 → 161,7 |
}; |
/** |
* struct drm_fb_helper - helper to emulate fbdev on top of kms |
* struct drm_fb_helper - main structure to emulate fbdev on top of KMS |
* @fb: Scanout framebuffer object |
* @dev: DRM device |
* @crtc_count: number of possible CRTCs |
112,11 → 168,15 |
* @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 |
* @connector_info: array of per-connector information |
* @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? |
* |
* This is the main structure used by the fbdev helpers. Drivers supporting |
* fbdev emulation should embedded this into their overall driver structure. |
* Drivers must also fill out a struct &drm_fb_helper_funcs with a few |
* operations. |
*/ |
struct drm_fb_helper { |
struct drm_framebuffer *fb; |
129,10 → 189,21 |
const struct drm_fb_helper_funcs *funcs; |
struct fb_info *fbdev; |
u32 pseudo_palette[17]; |
/** |
* @kernel_fb_list: |
* |
* Entry on the global kernel_fb_helper_list, used for kgdb entry/exit. |
*/ |
struct list_head kernel_fb_list; |
/* we got a hotplug but fbdev wasn't running the console |
delay until next set_par */ |
/** |
* @delayed_hotplug: |
* |
* A hotplug was received while fbdev wasn't in control of the DRM |
* device, i.e. another KMS master was active. The output configuration |
* needs to be reprobe when fbdev is in control again. |
*/ |
bool delayed_hotplug; |
/** |
/drivers/include/drm/drm_gem.h |
---|
35,34 → 35,68 |
*/ |
/** |
* This structure defines the drm_mm memory object, which will be used by the |
* DRM for its buffer objects. |
* struct drm_gem_object - GEM buffer object |
* |
* This structure defines the generic parts for GEM buffer objects, which are |
* mostly around handling mmap and userspace handles. |
* |
* Buffer objects are often abbreviated to BO. |
*/ |
struct drm_gem_object { |
/** Reference count of this object */ |
/** |
* @refcount: |
* |
* Reference count of this object |
* |
* Please use drm_gem_object_reference() to acquire and |
* drm_gem_object_unreference() or drm_gem_object_unreference_unlocked() |
* to release a reference to a GEM buffer object. |
*/ |
struct kref refcount; |
/** |
* handle_count - gem file_priv handle count of this object |
* @handle_count: |
* |
* This is the GEM file_priv handle count of this object. |
* |
* Each handle also holds a reference. Note that when the handle_count |
* drops to 0 any global names (e.g. the id in the flink namespace) will |
* be cleared. |
* |
* Protected by dev->object_name_lock. |
* */ |
*/ |
unsigned handle_count; |
/** Related drm device */ |
/** |
* @dev: DRM dev this object belongs to. |
*/ |
struct drm_device *dev; |
/** File representing the shmem storage */ |
/** |
* @filp: |
* |
* SHMEM file node used as backing storage for swappable buffer objects. |
* GEM also supports driver private objects with driver-specific backing |
* storage (contiguous CMA memory, special reserved blocks). In this |
* case @filp is NULL. |
*/ |
struct file *filp; |
/* Mapping info for this object */ |
/** |
* @vma_node: |
* |
* Mapping info for this object to support mmap. Drivers are supposed to |
* allocate the mmap offset using drm_gem_create_mmap_offset(). The |
* offset itself can be retrieved using drm_vma_node_offset_addr(). |
* |
* Memory mapping itself is handled by drm_gem_mmap(), which also checks |
* that userspace is allowed to access the object. |
*/ |
struct drm_vma_offset_node vma_node; |
/** |
* @size: |
* |
* Size of the object, in bytes. Immutable over the object's |
* lifetime. |
*/ |
69,21 → 103,32 |
size_t size; |
/** |
* @name: |
* |
* Global name for this object, starts at 1. 0 means unnamed. |
* Access is covered by the object_name_lock in the related drm_device |
* Access is covered by dev->object_name_lock. This is used by the GEM_FLINK |
* and GEM_OPEN ioctls. |
*/ |
int name; |
/** |
* Memory domains. These monitor which caches contain read/write data |
* @read_domains: |
* |
* Read memory domains. These monitor which caches contain read/write data |
* related to the object. When transitioning from one set of domains |
* to another, the driver is called to ensure that caches are suitably |
* flushed and invalidated |
* flushed and invalidated. |
*/ |
uint32_t read_domains; |
/** |
* @write_domain: Corresponding unique write memory domain. |
*/ |
uint32_t write_domain; |
/** |
* @pending_read_domains: |
* |
* While validating an exec operation, the |
* new read/write domain values are computed here. |
* They will be transferred to the above values |
90,22 → 135,30 |
* at the point that any cache flushing occurs |
*/ |
uint32_t pending_read_domains; |
/** |
* @pending_write_domain: Write domain similar to @pending_read_domains. |
*/ |
uint32_t pending_write_domain; |
/** |
* dma_buf - dma buf associated with this GEM object |
* @dma_buf: |
* |
* dma-buf associated with this GEM object. |
* |
* Pointer to the dma-buf associated with this gem object (either |
* through importing or exporting). We break the resulting reference |
* loop when the last gem handle for this object is released. |
* |
* Protected by obj->object_name_lock |
* Protected by obj->object_name_lock. |
*/ |
struct dma_buf *dma_buf; |
/** |
* import_attach - dma buf attachment backing this object |
* @import_attach: |
* |
* dma-buf attachment backing this object. |
* |
* Any foreign dma_buf imported as a gem object has this set to the |
* attachment point for the device. This is invariant over the lifetime |
* of a gem object. |
133,6 → 186,13 |
struct vm_area_struct *vma); |
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); |
/** |
* drm_gem_object_reference - acquire a GEM BO reference |
* @obj: GEM buffer object |
* |
* This acquires additional reference to @obj. It is illegal to call this |
* without already holding a reference. No locks required. |
*/ |
static inline void |
drm_gem_object_reference(struct drm_gem_object *obj) |
{ |
139,6 → 199,17 |
kref_get(&obj->refcount); |
} |
/** |
* drm_gem_object_unreference - release a GEM BO reference |
* @obj: GEM buffer object |
* |
* This releases a reference to @obj. Callers must hold the dev->struct_mutex |
* lock when calling this function, even when the driver doesn't use |
* dev->struct_mutex for anything. |
* |
* For drivers not encumbered with legacy locking use |
* drm_gem_object_unreference_unlocked() instead. |
*/ |
static inline void |
drm_gem_object_unreference(struct drm_gem_object *obj) |
{ |
149,6 → 220,13 |
} |
} |
/** |
* drm_gem_object_unreference_unlocked - release a GEM BO reference |
* @obj: GEM buffer object |
* |
* This releases a reference to @obj. Callers must not hold the |
* dev->struct_mutex lock when calling this function. |
*/ |
static inline void |
drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) |
{ |
/drivers/include/drm/drm_mipi_dsi.h |
---|
163,9 → 163,36 |
return container_of(dev, struct mipi_dsi_device, dev); |
} |
/** |
* mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any |
* given pixel format defined by the MIPI DSI |
* specification |
* @fmt: MIPI DSI pixel format |
* |
* Returns: The number of bits per pixel of the given pixel format. |
*/ |
static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) |
{ |
switch (fmt) { |
case MIPI_DSI_FMT_RGB888: |
case MIPI_DSI_FMT_RGB666: |
return 24; |
case MIPI_DSI_FMT_RGB666_PACKED: |
return 18; |
case MIPI_DSI_FMT_RGB565: |
return 16; |
} |
return -EINVAL; |
} |
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_shutdown_peripheral(struct mipi_dsi_device *dsi); |
int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi); |
int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, |
u16 value); |
/drivers/include/drm/drm_mm.h |
---|
148,8 → 148,7 |
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; |
return list_next_entry(hole_node, node_list)->start; |
} |
/** |
180,6 → 179,14 |
&(mm)->head_node.node_list, \ |
node_list) |
#define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \ |
for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : (mm)->hole_stack.next, struct drm_mm_node, hole_stack); \ |
&entry->hole_stack != &(mm)->hole_stack ? \ |
hole_start = drm_mm_hole_node_start(entry), \ |
hole_end = drm_mm_hole_node_end(entry), \ |
1 : 0; \ |
entry = list_entry((backwards) ? entry->hole_stack.prev : entry->hole_stack.next, struct drm_mm_node, hole_stack)) |
/** |
* drm_mm_for_each_hole - iterator to walk over all holes |
* @entry: drm_mm_node used internally to track progress |
200,21 → 207,8 |
* going backwards. |
*/ |
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \ |
for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \ |
&entry->hole_stack != &(mm)->hole_stack ? \ |
hole_start = drm_mm_hole_node_start(entry), \ |
hole_end = drm_mm_hole_node_end(entry), \ |
1 : 0; \ |
entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack)) |
__drm_mm_for_each_hole(entry, mm, hole_start, hole_end, 0) |
#define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \ |
for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : (mm)->hole_stack.next, struct drm_mm_node, hole_stack); \ |
&entry->hole_stack != &(mm)->hole_stack ? \ |
hole_start = drm_mm_hole_node_start(entry), \ |
hole_end = drm_mm_hole_node_end(entry), \ |
1 : 0; \ |
entry = list_entry((backwards) ? entry->hole_stack.prev : entry->hole_stack.next, struct drm_mm_node, hole_stack)) |
/* |
* Basic range manager support (drm_mm.c) |
*/ |
/drivers/include/drm/drm_modes.h |
---|
35,46 → 35,91 |
* structures). |
*/ |
/** |
* enum drm_mode_status - hardware support status of a mode |
* @MODE_OK: Mode OK |
* @MODE_HSYNC: hsync out of range |
* @MODE_VSYNC: vsync out of range |
* @MODE_H_ILLEGAL: mode has illegal horizontal timings |
* @MODE_V_ILLEGAL: mode has illegal horizontal timings |
* @MODE_BAD_WIDTH: requires an unsupported linepitch |
* @MODE_NOMODE: no mode with a matching name |
* @MODE_NO_INTERLACE: interlaced mode not supported |
* @MODE_NO_DBLESCAN: doublescan mode not supported |
* @MODE_NO_VSCAN: multiscan mode not supported |
* @MODE_MEM: insufficient video memory |
* @MODE_VIRTUAL_X: mode width too large for specified virtual size |
* @MODE_VIRTUAL_Y: mode height too large for specified virtual size |
* @MODE_MEM_VIRT: insufficient video memory given virtual size |
* @MODE_NOCLOCK: no fixed clock available |
* @MODE_CLOCK_HIGH: clock required is too high |
* @MODE_CLOCK_LOW: clock required is too low |
* @MODE_CLOCK_RANGE: clock/mode isn't in a ClockRange |
* @MODE_BAD_HVALUE: horizontal timing was out of range |
* @MODE_BAD_VVALUE: vertical timing was out of range |
* @MODE_BAD_VSCAN: VScan value out of range |
* @MODE_HSYNC_NARROW: horizontal sync too narrow |
* @MODE_HSYNC_WIDE: horizontal sync too wide |
* @MODE_HBLANK_NARROW: horizontal blanking too narrow |
* @MODE_HBLANK_WIDE: horizontal blanking too wide |
* @MODE_VSYNC_NARROW: vertical sync too narrow |
* @MODE_VSYNC_WIDE: vertical sync too wide |
* @MODE_VBLANK_NARROW: vertical blanking too narrow |
* @MODE_VBLANK_WIDE: vertical blanking too wide |
* @MODE_PANEL: exceeds panel dimensions |
* @MODE_INTERLACE_WIDTH: width too large for interlaced mode |
* @MODE_ONE_WIDTH: only one width is supported |
* @MODE_ONE_HEIGHT: only one height is supported |
* @MODE_ONE_SIZE: only one resolution is supported |
* @MODE_NO_REDUCED: monitor doesn't accept reduced blanking |
* @MODE_NO_STEREO: stereo modes not supported |
* @MODE_STALE: mode has become stale |
* @MODE_BAD: unspecified reason |
* @MODE_ERROR: error condition |
* |
* This enum is used to filter out modes not supported by the driver/hardware |
* combination. |
*/ |
enum drm_mode_status { |
MODE_OK = 0, /* Mode OK */ |
MODE_HSYNC, /* hsync out of range */ |
MODE_VSYNC, /* vsync out of range */ |
MODE_H_ILLEGAL, /* mode has illegal horizontal timings */ |
MODE_V_ILLEGAL, /* mode has illegal horizontal timings */ |
MODE_BAD_WIDTH, /* requires an unsupported linepitch */ |
MODE_NOMODE, /* no mode with a matching name */ |
MODE_NO_INTERLACE, /* interlaced mode not supported */ |
MODE_NO_DBLESCAN, /* doublescan mode not supported */ |
MODE_NO_VSCAN, /* multiscan mode not supported */ |
MODE_MEM, /* insufficient video memory */ |
MODE_VIRTUAL_X, /* mode width too large for specified virtual size */ |
MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */ |
MODE_MEM_VIRT, /* insufficient video memory given virtual size */ |
MODE_NOCLOCK, /* no fixed clock available */ |
MODE_CLOCK_HIGH, /* clock required is too high */ |
MODE_CLOCK_LOW, /* clock required is too low */ |
MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */ |
MODE_BAD_HVALUE, /* horizontal timing was out of range */ |
MODE_BAD_VVALUE, /* vertical timing was out of range */ |
MODE_BAD_VSCAN, /* VScan value out of range */ |
MODE_HSYNC_NARROW, /* horizontal sync too narrow */ |
MODE_HSYNC_WIDE, /* horizontal sync too wide */ |
MODE_HBLANK_NARROW, /* horizontal blanking too narrow */ |
MODE_HBLANK_WIDE, /* horizontal blanking too wide */ |
MODE_VSYNC_NARROW, /* vertical sync too narrow */ |
MODE_VSYNC_WIDE, /* vertical sync too wide */ |
MODE_VBLANK_NARROW, /* vertical blanking too narrow */ |
MODE_VBLANK_WIDE, /* vertical blanking too wide */ |
MODE_PANEL, /* exceeds panel dimensions */ |
MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */ |
MODE_ONE_WIDTH, /* only one width is supported */ |
MODE_ONE_HEIGHT, /* only one height is supported */ |
MODE_ONE_SIZE, /* only one resolution is supported */ |
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ |
MODE_NO_STEREO, /* stereo modes not supported */ |
MODE_UNVERIFIED = -3, /* mode needs to reverified */ |
MODE_BAD = -2, /* unspecified reason */ |
MODE_ERROR = -1 /* error condition */ |
MODE_OK = 0, |
MODE_HSYNC, |
MODE_VSYNC, |
MODE_H_ILLEGAL, |
MODE_V_ILLEGAL, |
MODE_BAD_WIDTH, |
MODE_NOMODE, |
MODE_NO_INTERLACE, |
MODE_NO_DBLESCAN, |
MODE_NO_VSCAN, |
MODE_MEM, |
MODE_VIRTUAL_X, |
MODE_VIRTUAL_Y, |
MODE_MEM_VIRT, |
MODE_NOCLOCK, |
MODE_CLOCK_HIGH, |
MODE_CLOCK_LOW, |
MODE_CLOCK_RANGE, |
MODE_BAD_HVALUE, |
MODE_BAD_VVALUE, |
MODE_BAD_VSCAN, |
MODE_HSYNC_NARROW, |
MODE_HSYNC_WIDE, |
MODE_HBLANK_NARROW, |
MODE_HBLANK_WIDE, |
MODE_VSYNC_NARROW, |
MODE_VSYNC_WIDE, |
MODE_VBLANK_NARROW, |
MODE_VBLANK_WIDE, |
MODE_PANEL, |
MODE_INTERLACE_WIDTH, |
MODE_ONE_WIDTH, |
MODE_ONE_HEIGHT, |
MODE_ONE_SIZE, |
MODE_NO_REDUCED, |
MODE_NO_STEREO, |
MODE_STALE = -3, |
MODE_BAD = -2, |
MODE_ERROR = -1 |
}; |
#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \ |
96,17 → 141,125 |
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF |
/** |
* struct drm_display_mode - DRM kernel-internal display mode structure |
* @hdisplay: horizontal display size |
* @hsync_start: horizontal sync start |
* @hsync_end: horizontal sync end |
* @htotal: horizontal total size |
* @hskew: horizontal skew?! |
* @vdisplay: vertical display size |
* @vsync_start: vertical sync start |
* @vsync_end: vertical sync end |
* @vtotal: vertical total size |
* @vscan: vertical scan?! |
* @crtc_hdisplay: hardware mode horizontal display size |
* @crtc_hblank_start: hardware mode horizontal blank start |
* @crtc_hblank_end: hardware mode horizontal blank end |
* @crtc_hsync_start: hardware mode horizontal sync start |
* @crtc_hsync_end: hardware mode horizontal sync end |
* @crtc_htotal: hardware mode horizontal total size |
* @crtc_hskew: hardware mode horizontal skew?! |
* @crtc_vdisplay: hardware mode vertical display size |
* @crtc_vblank_start: hardware mode vertical blank start |
* @crtc_vblank_end: hardware mode vertical blank end |
* @crtc_vsync_start: hardware mode vertical sync start |
* @crtc_vsync_end: hardware mode vertical sync end |
* @crtc_vtotal: hardware mode vertical total size |
* |
* The horizontal and vertical timings are defined per the following diagram. |
* |
* |
* Active Front Sync Back |
* Region Porch Porch |
* <-----------------------><----------------><-------------><--------------> |
* //////////////////////| |
* ////////////////////// | |
* ////////////////////// |.................. ................ |
* _______________ |
* <----- [hv]display -----> |
* <------------- [hv]sync_start ------------> |
* <--------------------- [hv]sync_end ---------------------> |
* <-------------------------------- [hv]total ----------------------------->* |
* |
* This structure contains two copies of timings. First are the plain timings, |
* which specify the logical mode, as it would be for a progressive 1:1 scanout |
* at the refresh rate userspace can observe through vblank timestamps. Then |
* there's the hardware timings, which are corrected for interlacing, |
* double-clocking and similar things. They are provided as a convenience, and |
* can be appropriately computed using drm_mode_set_crtcinfo(). |
*/ |
struct drm_display_mode { |
/* Header */ |
/** |
* @head: |
* |
* struct list_head for mode lists. |
*/ |
struct list_head head; |
/** |
* @base: |
* |
* A display mode is a normal modeset object, possibly including public |
* userspace id. |
* |
* FIXME: |
* |
* This can probably be removed since the entire concept of userspace |
* managing modes explicitly has never landed in upstream kernel mode |
* setting support. |
*/ |
struct drm_mode_object base; |
/** |
* @name: |
* |
* Human-readable name of the mode, filled out with drm_mode_set_name(). |
*/ |
char name[DRM_DISPLAY_MODE_LEN]; |
/** |
* @status: |
* |
* Status of the mode, used to filter out modes not supported by the |
* hardware. See enum &drm_mode_status. |
*/ |
enum drm_mode_status status; |
/** |
* @type: |
* |
* A bitmask of flags, mostly about the source of a mode. Possible flags |
* are: |
* |
* - DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, effectively |
* unused. |
* - DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native |
* resolution of an LCD panel. There should only be one preferred |
* mode per connector at any given time. |
* - DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of |
* them really. Drivers must set this bit for all modes they create |
* and expose to userspace. |
* |
* Plus a big list of flags which shouldn't be used at all, but are |
* still around since these flags are also used in the userspace ABI: |
* |
* - DRM_MODE_TYPE_DEFAULT: Again a leftover, use |
* DRM_MODE_TYPE_PREFERRED instead. |
* - DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers |
* which are stuck around for hysterical raisins only. No one has an |
* idea what they were meant for. Don't use. |
* - DRM_MODE_TYPE_USERDEF: Mode defined by userspace, again a vestige |
* from older kms designs where userspace had to first add a custom |
* mode to the kernel's mode list before it could use it. Don't use. |
*/ |
unsigned int type; |
/* Proposed mode values */ |
/** |
* @clock: |
* |
* Pixel clock in kHz. |
*/ |
int clock; /* in kHz */ |
int hdisplay; |
int hsync_start; |
118,14 → 271,74 |
int vsync_end; |
int vtotal; |
int vscan; |
/** |
* @flags: |
* |
* Sync and timing flags: |
* |
* - DRM_MODE_FLAG_PHSYNC: horizontal sync is active high. |
* - DRM_MODE_FLAG_NHSYNC: horizontal sync is active low. |
* - DRM_MODE_FLAG_PVSYNC: vertical sync is active high. |
* - DRM_MODE_FLAG_NVSYNC: vertical sync is active low. |
* - DRM_MODE_FLAG_INTERLACE: mode is interlaced. |
* - DRM_MODE_FLAG_DBLSCAN: mode uses doublescan. |
* - DRM_MODE_FLAG_CSYNC: mode uses composite sync. |
* - DRM_MODE_FLAG_PCSYNC: composite sync is active high. |
* - DRM_MODE_FLAG_NCSYNC: composite sync is active low. |
* - DRM_MODE_FLAG_HSKEW: hskew provided (not used?). |
* - DRM_MODE_FLAG_BCAST: not used? |
* - DRM_MODE_FLAG_PIXMUX: not used? |
* - DRM_MODE_FLAG_DBLCLK: double-clocked mode. |
* - DRM_MODE_FLAG_CLKDIV2: half-clocked mode. |
* |
* Additionally there's flags to specify how 3D modes are packed: |
* |
* - DRM_MODE_FLAG_3D_NONE: normal, non-3D mode. |
* - DRM_MODE_FLAG_3D_FRAME_PACKING: 2 full frames for left and right. |
* - DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: interleaved like fields. |
* - DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: interleaved lines. |
* - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: side-by-side full frames. |
* - DRM_MODE_FLAG_3D_L_DEPTH: ? |
* - DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ? |
* - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: frame split into top and bottom |
* parts. |
* - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: frame split into left and |
* right parts. |
*/ |
unsigned int flags; |
/* Addressable image size (may be 0 for projectors, etc.) */ |
/** |
* @width_mm: |
* |
* Addressable size of the output in mm, projectors should set this to |
* 0. |
*/ |
int width_mm; |
/** |
* @height_mm: |
* |
* Addressable size of the output in mm, projectors should set this to |
* 0. |
*/ |
int height_mm; |
/* Actual mode we give to hw */ |
int crtc_clock; /* in KHz */ |
/** |
* @crtc_clock: |
* |
* Actual pixel or dot clock in the hardware. This differs from the |
* logical @clock when e.g. using interlacing, double-clocking, stereo |
* modes or other fancy stuff that changes the timings and signals |
* actually sent over the wire. |
* |
* This is again in kHz. |
* |
* Note that with digital outputs like HDMI or DP there's usually a |
* massive confusion between the dot clock and the signal clock at the |
* bit encoding level. Especially when a 8b/10b encoding is used and the |
* difference is exactly a factor of 10. |
*/ |
int crtc_clock; |
int crtc_hdisplay; |
int crtc_hblank_start; |
int crtc_hblank_end; |
140,12 → 353,48 |
int crtc_vsync_end; |
int crtc_vtotal; |
/* Driver private mode info */ |
/** |
* @private: |
* |
* Pointer for driver private data. This can only be used for mode |
* objects passed to drivers in modeset operations. It shouldn't be used |
* by atomic drivers since they can store any additional data by |
* subclassing state structures. |
*/ |
int *private; |
/** |
* @private_flags: |
* |
* Similar to @private, but just an integer. |
*/ |
int private_flags; |
int vrefresh; /* in Hz */ |
int hsync; /* in kHz */ |
/** |
* @vrefresh: |
* |
* Vertical refresh rate, for debug output in human readable form. Not |
* used in a functional way. |
* |
* This value is in Hz. |
*/ |
int vrefresh; |
/** |
* @hsync: |
* |
* Horizontal refresh rate, for debug output in human readable form. Not |
* used in a functional way. |
* |
* This value is in kHz. |
*/ |
int hsync; |
/** |
* @picture_aspect_ratio: |
* |
* Field for setting the HDMI picture aspect ratio of a mode. |
*/ |
enum hdmi_picture_aspect picture_aspect_ratio; |
}; |
222,6 → 471,8 |
const struct drm_display_mode *mode); |
bool drm_mode_equal(const struct drm_display_mode *mode1, |
const struct drm_display_mode *mode2); |
bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1, |
const struct drm_display_mode *mode2); |
bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, |
const struct drm_display_mode *mode2); |
232,7 → 483,7 |
void drm_mode_prune_invalid(struct drm_device *dev, |
struct list_head *mode_list, bool verbose); |
void drm_mode_sort(struct list_head *mode_list); |
void drm_mode_connector_list_update(struct drm_connector *connector, bool merge_type_bits); |
void drm_mode_connector_list_update(struct drm_connector *connector); |
/* parsing cmdline modes */ |
bool |
/drivers/include/drm/drm_modeset_helper_vtables.h |
---|
0,0 → 1,928 |
/* |
* Copyright © 2006 Keith Packard |
* Copyright © 2007-2008 Dave Airlie |
* Copyright © 2007-2008 Intel Corporation |
* Jesse Barnes <jesse.barnes@intel.com> |
* Copyright © 2011-2013 Intel Corporation |
* Copyright © 2015 Intel Corporation |
* Daniel Vetter <daniel.vetter@ffwll.ch> |
* |
* 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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_MODESET_HELPER_VTABLES_H__ |
#define __DRM_MODESET_HELPER_VTABLES_H__ |
#include <drm/drm_crtc.h> |
/** |
* DOC: overview |
* |
* The DRM mode setting helper functions are common code for drivers to use if |
* they wish. Drivers are not forced to use this code in their |
* implementations but it would be useful if the code they do use at least |
* provides a consistent interface and operation to userspace. Therefore it is |
* highly recommended to use the provided helpers as much as possible. |
* |
* Because there is only one pointer per modeset object to hold a vfunc table |
* for helper libraries they are by necessity shared among the different |
* helpers. |
* |
* To make this clear all the helper vtables are pulled together in this location here. |
*/ |
enum mode_set_atomic; |
/** |
* struct drm_crtc_helper_funcs - helper operations for CRTCs |
* |
* These hooks are used by the legacy CRTC helpers, the transitional plane |
* helpers and the new atomic modesetting helpers. |
*/ |
struct drm_crtc_helper_funcs { |
/** |
* @dpms: |
* |
* Callback to control power levels on the CRTC. If the mode passed in |
* is unsupported, the provider must use the next lowest power level. |
* This is used by the legacy CRTC helpers to implement DPMS |
* functionality in drm_helper_connector_dpms(). |
* |
* This callback is also used to disable a CRTC by calling it with |
* DRM_MODE_DPMS_OFF if the @disable hook isn't used. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for enabling and disabling a CRTC to |
* facilitate transitions to atomic, but it is deprecated. Instead |
* @enable and @disable should be used. |
*/ |
void (*dpms)(struct drm_crtc *crtc, int mode); |
/** |
* @prepare: |
* |
* This callback should prepare the CRTC for a subsequent modeset, which |
* in practice means the driver should disable the CRTC if it is |
* running. Most drivers ended up implementing this by calling their |
* @dpms hook with DRM_MODE_DPMS_OFF. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for disabling a CRTC to facilitate |
* transitions to atomic, but it is deprecated. Instead @disable should |
* be used. |
*/ |
void (*prepare)(struct drm_crtc *crtc); |
/** |
* @commit: |
* |
* This callback should commit the new mode on the CRTC after a modeset, |
* which in practice means the driver should enable the CRTC. Most |
* drivers ended up implementing this by calling their @dpms hook with |
* DRM_MODE_DPMS_ON. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for enabling a CRTC to facilitate |
* transitions to atomic, but it is deprecated. Instead @enable should |
* be used. |
*/ |
void (*commit)(struct drm_crtc *crtc); |
/** |
* @mode_fixup: |
* |
* This callback is used to validate a mode. The parameter mode is the |
* display mode that userspace requested, adjusted_mode is the mode the |
* encoders need to be fed with. Note that this is the inverse semantics |
* of the meaning for the &drm_encoder and &drm_bridge |
* ->mode_fixup() functions. If the CRTC cannot support the requested |
* conversion from mode to adjusted_mode it should reject the modeset. |
* |
* This function is used by both legacy CRTC helpers and atomic helpers. |
* With atomic helpers it is optional. |
* |
* NOTE: |
* |
* This function is called in the check phase of atomic modesets, which |
* can be aborted for any reason (including on userspace's request to |
* just check whether a configuration would be possible). Atomic drivers |
* MUST NOT touch any persistent state (hardware or software) or data |
* structures except the passed in adjusted_mode parameter. |
* |
* This is in contrast to the legacy CRTC helpers where this was |
* allowed. |
* |
* Atomic drivers which need to inspect and adjust more state should |
* instead use the @atomic_check callback. |
* |
* Also beware that neither core nor helpers filter modes before |
* passing them to the driver: While the list of modes that is |
* advertised to userspace is filtered using the connector's |
* ->mode_valid() callback, neither the core nor the helpers do any |
* filtering on modes passed in from userspace when setting a mode. It |
* is therefore possible for userspace to pass in a mode that was |
* previously filtered out using ->mode_valid() or add a custom mode |
* that wasn't probed from EDID or similar to begin with. Even though |
* this is an advanced feature and rarely used nowadays, some users rely |
* on being able to specify modes manually so drivers must be prepared |
* to deal with it. Specifically this means that all drivers need not |
* only validate modes in ->mode_valid() but also in ->mode_fixup() to |
* make sure invalid modes passed in from userspace are rejected. |
* |
* RETURNS: |
* |
* True if an acceptable configuration is possible, false if the modeset |
* operation should be rejected. |
*/ |
bool (*mode_fixup)(struct drm_crtc *crtc, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/** |
* @mode_set: |
* |
* This callback is used by the legacy CRTC helpers to set a new mode, |
* position and framebuffer. Since it ties the primary plane to every |
* mode change it is incompatible with universal plane support. And |
* since it can't update other planes it's incompatible with atomic |
* modeset support. |
* |
* This callback is only used by CRTC helpers and deprecated. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
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); |
/** |
* @mode_set_nofb: |
* |
* This callback is used to update the display mode of a CRTC without |
* changing anything of the primary plane configuration. This fits the |
* requirement of atomic and hence is used by the atomic helpers. It is |
* also used by the transitional plane helpers to implement a |
* @mode_set hook in drm_helper_crtc_mode_set(). |
* |
* Note that the display pipe is completely off when this function is |
* called. Atomic drivers which need hardware to be running before they |
* program the new display mode (e.g. because they implement runtime PM) |
* should not use this hook. This is because the helper library calls |
* this hook only once per mode change and not every time the display |
* pipeline is suspended using either DPMS or the new "ACTIVE" property. |
* Which means register values set in this callback might get reset when |
* the CRTC is suspended, but not restored. Such drivers should instead |
* move all their CRTC setup into the @enable callback. |
* |
* This callback is optional. |
*/ |
void (*mode_set_nofb)(struct drm_crtc *crtc); |
/** |
* @mode_set_base: |
* |
* This callback is used by the legacy CRTC helpers to set a new |
* framebuffer and scanout position. It is optional and used as an |
* optimized fast-path instead of a full mode set operation with all the |
* resulting flickering. If it is not present |
* drm_crtc_helper_set_config() will fall back to a full modeset, using |
* the ->mode_set() callback. Since it can't update other planes it's |
* incompatible with atomic modeset support. |
* |
* This callback is only used by the CRTC helpers and deprecated. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, |
struct drm_framebuffer *old_fb); |
/** |
* @mode_set_base_atomic: |
* |
* This callback is used by the fbdev helpers to set a new framebuffer |
* and scanout without sleeping, i.e. from an atomic calling context. It |
* is only used to implement kgdb support. |
* |
* This callback is optional and only needed for kgdb support in the fbdev |
* helpers. |
* |
* RETURNS: |
* |
* 0 on success or a negative error code on failure. |
*/ |
int (*mode_set_base_atomic)(struct drm_crtc *crtc, |
struct drm_framebuffer *fb, int x, int y, |
enum mode_set_atomic); |
/** |
* @load_lut: |
* |
* Load a LUT prepared with the @gamma_set functions from |
* &drm_fb_helper_funcs. |
* |
* This callback is optional and is only used by the fbdev emulation |
* helpers. |
* |
* FIXME: |
* |
* This callback is functionally redundant with the core gamma table |
* support and simply exists because the fbdev hasn't yet been |
* refactored to use the core gamma table interfaces. |
*/ |
void (*load_lut)(struct drm_crtc *crtc); |
/** |
* @disable: |
* |
* This callback should be used to disable the CRTC. With the atomic |
* drivers it is called after all encoders connected to this CRTC have |
* been shut off already using their own ->disable hook. If that |
* sequence is too simple drivers can just add their own hooks and call |
* it from this CRTC callback here by looping over all encoders |
* connected to it using for_each_encoder_on_crtc(). |
* |
* This hook is used both by legacy CRTC helpers and atomic helpers. |
* Atomic drivers don't need to implement it if there's no need to |
* disable anything at the CRTC level. To ensure that runtime PM |
* handling (using either DPMS or the new "ACTIVE" property) works |
* @disable must be the inverse of @enable for atomic drivers. |
* |
* NOTE: |
* |
* With legacy CRTC helpers there's a big semantic difference between |
* @disable and other hooks (like @prepare or @dpms) used to shut down a |
* CRTC: @disable is only called when also logically disabling the |
* display pipeline and needs to release any resources acquired in |
* @mode_set (like shared PLLs, or again release pinned framebuffers). |
* |
* Therefore @disable must be the inverse of @mode_set plus @commit for |
* drivers still using legacy CRTC helpers, which is different from the |
* rules under atomic. |
*/ |
void (*disable)(struct drm_crtc *crtc); |
/** |
* @enable: |
* |
* This callback should be used to enable the CRTC. With the atomic |
* drivers it is called before all encoders connected to this CRTC are |
* enabled through the encoder's own ->enable hook. If that sequence is |
* too simple drivers can just add their own hooks and call it from this |
* CRTC callback here by looping over all encoders connected to it using |
* for_each_encoder_on_crtc(). |
* |
* This hook is used only by atomic helpers, for symmetry with @disable. |
* Atomic drivers don't need to implement it if there's no need to |
* enable anything at the CRTC level. To ensure that runtime PM handling |
* (using either DPMS or the new "ACTIVE" property) works |
* @enable must be the inverse of @disable for atomic drivers. |
*/ |
void (*enable)(struct drm_crtc *crtc); |
/** |
* @atomic_check: |
* |
* Drivers should check plane-update related CRTC constraints in this |
* hook. They can also check mode related limitations but need to be |
* aware of the calling order, since this hook is used by |
* drm_atomic_helper_check_planes() whereas the preparations needed to |
* check output routing and the display mode is done in |
* drm_atomic_helper_check_modeset(). Therefore drivers that want to |
* check output routing and display mode constraints in this callback |
* must ensure that drm_atomic_helper_check_modeset() has been called |
* beforehand. This is calling order used by the default helper |
* implementation in drm_atomic_helper_check(). |
* |
* When using drm_atomic_helper_check_planes() CRTCs' ->atomic_check() |
* hooks are called after the ones for planes, which allows drivers to |
* assign shared resources requested by planes in the CRTC callback |
* here. For more complicated dependencies the driver can call the provided |
* check helpers multiple times until the computed state has a final |
* configuration and everything has been checked. |
* |
* This function is also allowed to inspect any other object's state and |
* can add more state objects to the atomic commit if needed. Care must |
* be taken though to ensure that state check&compute functions for |
* these added states are all called, and derived state in other objects |
* all updated. Again the recommendation is to just call check helpers |
* until a maximal configuration is reached. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
* |
* NOTE: |
* |
* This function is called in the check phase of an atomic update. The |
* driver is not allowed to change anything outside of the free-standing |
* state objects passed-in or assembled in the overall &drm_atomic_state |
* update tracking structure. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the state or the transition can't be |
* supported, -ENOMEM on memory allocation failure and -EDEADLK if an |
* attempt to obtain another state object ran into a &drm_modeset_lock |
* deadlock. |
*/ |
int (*atomic_check)(struct drm_crtc *crtc, |
struct drm_crtc_state *state); |
/** |
* @atomic_begin: |
* |
* Drivers should prepare for an atomic update of multiple planes on |
* a CRTC in this hook. Depending upon hardware this might be vblank |
* evasion, blocking updates by setting bits or doing preparatory work |
* for e.g. manual update display. |
* |
* This hook is called before any plane commit functions are called. |
* |
* Note that the power state of the display pipe when this function is |
* called depends upon the exact helpers and calling sequence the driver |
* has picked. See drm_atomic_commit_planes() for a discussion of the |
* tradeoffs and variants of plane commit helpers. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
*/ |
void (*atomic_begin)(struct drm_crtc *crtc, |
struct drm_crtc_state *old_crtc_state); |
/** |
* @atomic_flush: |
* |
* Drivers should finalize an atomic update of multiple planes on |
* a CRTC in this hook. Depending upon hardware this might include |
* checking that vblank evasion was successful, unblocking updates by |
* setting bits or setting the GO bit to flush out all updates. |
* |
* Simple hardware or hardware with special requirements can commit and |
* flush out all updates for all planes from this hook and forgo all the |
* other commit hooks for plane updates. |
* |
* This hook is called after any plane commit functions are called. |
* |
* Note that the power state of the display pipe when this function is |
* called depends upon the exact helpers and calling sequence the driver |
* has picked. See drm_atomic_commit_planes() for a discussion of the |
* tradeoffs and variants of plane commit helpers. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
*/ |
void (*atomic_flush)(struct drm_crtc *crtc, |
struct drm_crtc_state *old_crtc_state); |
}; |
/** |
* drm_crtc_helper_add - sets the helper vtable for a crtc |
* @crtc: DRM CRTC |
* @funcs: helper vtable to set for @crtc |
*/ |
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, |
const struct drm_crtc_helper_funcs *funcs) |
{ |
crtc->helper_private = funcs; |
} |
/** |
* struct drm_encoder_helper_funcs - helper operations for encoders |
* |
* These hooks are used by the legacy CRTC helpers, the transitional plane |
* helpers and the new atomic modesetting helpers. |
*/ |
struct drm_encoder_helper_funcs { |
/** |
* @dpms: |
* |
* Callback to control power levels on the encoder. If the mode passed in |
* is unsupported, the provider must use the next lowest power level. |
* This is used by the legacy encoder helpers to implement DPMS |
* functionality in drm_helper_connector_dpms(). |
* |
* This callback is also used to disable an encoder by calling it with |
* DRM_MODE_DPMS_OFF if the @disable hook isn't used. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for enabling and disabling an encoder to |
* facilitate transitions to atomic, but it is deprecated. Instead |
* @enable and @disable should be used. |
*/ |
void (*dpms)(struct drm_encoder *encoder, int mode); |
/** |
* @mode_fixup: |
* |
* This callback is used to validate and adjust a mode. The parameter |
* mode is the display mode that should be fed to the next element in |
* the display chain, either the final &drm_connector or a &drm_bridge. |
* The parameter adjusted_mode is the input mode the encoder requires. It |
* can be modified by this callback and does not need to match mode. |
* |
* This function is used by both legacy CRTC helpers and atomic helpers. |
* With atomic helpers it is optional. |
* |
* NOTE: |
* |
* This function is called in the check phase of atomic modesets, which |
* can be aborted for any reason (including on userspace's request to |
* just check whether a configuration would be possible). Atomic drivers |
* MUST NOT touch any persistent state (hardware or software) or data |
* structures except the passed in adjusted_mode parameter. |
* |
* This is in contrast to the legacy CRTC helpers where this was |
* allowed. |
* |
* Atomic drivers which need to inspect and adjust more state should |
* instead use the @atomic_check callback. |
* |
* Also beware that neither core nor helpers filter modes before |
* passing them to the driver: While the list of modes that is |
* advertised to userspace is filtered using the connector's |
* ->mode_valid() callback, neither the core nor the helpers do any |
* filtering on modes passed in from userspace when setting a mode. It |
* is therefore possible for userspace to pass in a mode that was |
* previously filtered out using ->mode_valid() or add a custom mode |
* that wasn't probed from EDID or similar to begin with. Even though |
* this is an advanced feature and rarely used nowadays, some users rely |
* on being able to specify modes manually so drivers must be prepared |
* to deal with it. Specifically this means that all drivers need not |
* only validate modes in ->mode_valid() but also in ->mode_fixup() to |
* make sure invalid modes passed in from userspace are rejected. |
* |
* RETURNS: |
* |
* True if an acceptable configuration is possible, false if the modeset |
* operation should be rejected. |
*/ |
bool (*mode_fixup)(struct drm_encoder *encoder, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/** |
* @prepare: |
* |
* This callback should prepare the encoder for a subsequent modeset, |
* which in practice means the driver should disable the encoder if it |
* is running. Most drivers ended up implementing this by calling their |
* @dpms hook with DRM_MODE_DPMS_OFF. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for disabling an encoder to facilitate |
* transitions to atomic, but it is deprecated. Instead @disable should |
* be used. |
*/ |
void (*prepare)(struct drm_encoder *encoder); |
/** |
* @commit: |
* |
* This callback should commit the new mode on the encoder after a modeset, |
* which in practice means the driver should enable the encoder. Most |
* drivers ended up implementing this by calling their @dpms hook with |
* DRM_MODE_DPMS_ON. |
* |
* This callback is used by the legacy CRTC helpers. Atomic helpers |
* also support using this hook for enabling an encoder to facilitate |
* transitions to atomic, but it is deprecated. Instead @enable should |
* be used. |
*/ |
void (*commit)(struct drm_encoder *encoder); |
/** |
* @mode_set: |
* |
* This callback is used to update the display mode of an encoder. |
* |
* Note that the display pipe is completely off when this function is |
* called. Drivers which need hardware to be running before they program |
* the new display mode (because they implement runtime PM) should not |
* use this hook, because the helper library calls it only once and not |
* every time the display pipeline is suspend using either DPMS or the |
* new "ACTIVE" property. Such drivers should instead move all their |
* encoder setup into the ->enable() callback. |
* |
* This callback is used both by the legacy CRTC helpers and the atomic |
* modeset helpers. It is optional in the atomic helpers. |
*/ |
void (*mode_set)(struct drm_encoder *encoder, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode); |
/** |
* @get_crtc: |
* |
* This callback is used by the legacy CRTC helpers to work around |
* deficiencies in its own book-keeping. |
* |
* Do not use, use atomic helpers instead, which get the book keeping |
* right. |
* |
* FIXME: |
* |
* Currently only nouveau is using this, and as soon as nouveau is |
* atomic we can ditch this hook. |
*/ |
struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); |
/** |
* @detect: |
* |
* This callback can be used by drivers who want to do detection on the |
* encoder object instead of in connector functions. |
* |
* It is not used by any helper and therefore has purely driver-specific |
* semantics. New drivers shouldn't use this and instead just implement |
* their own private callbacks. |
* |
* FIXME: |
* |
* This should just be converted into a pile of driver vfuncs. |
* Currently radeon, amdgpu and nouveau are using it. |
*/ |
enum drm_connector_status (*detect)(struct drm_encoder *encoder, |
struct drm_connector *connector); |
/** |
* @disable: |
* |
* This callback should be used to disable the encoder. With the atomic |
* drivers it is called before this encoder's CRTC has been shut off |
* using the CRTC's own ->disable hook. If that sequence is too simple |
* drivers can just add their own driver private encoder hooks and call |
* them from CRTC's callback by looping over all encoders connected to |
* it using for_each_encoder_on_crtc(). |
* |
* This hook is used both by legacy CRTC helpers and atomic helpers. |
* Atomic drivers don't need to implement it if there's no need to |
* disable anything at the encoder level. To ensure that runtime PM |
* handling (using either DPMS or the new "ACTIVE" property) works |
* @disable must be the inverse of @enable for atomic drivers. |
* |
* NOTE: |
* |
* With legacy CRTC helpers there's a big semantic difference between |
* @disable and other hooks (like @prepare or @dpms) used to shut down a |
* encoder: @disable is only called when also logically disabling the |
* display pipeline and needs to release any resources acquired in |
* @mode_set (like shared PLLs, or again release pinned framebuffers). |
* |
* Therefore @disable must be the inverse of @mode_set plus @commit for |
* drivers still using legacy CRTC helpers, which is different from the |
* rules under atomic. |
*/ |
void (*disable)(struct drm_encoder *encoder); |
/** |
* @enable: |
* |
* This callback should be used to enable the encoder. With the atomic |
* drivers it is called after this encoder's CRTC has been enabled using |
* the CRTC's own ->enable hook. If that sequence is too simple drivers |
* can just add their own driver private encoder hooks and call them |
* from CRTC's callback by looping over all encoders connected to it |
* using for_each_encoder_on_crtc(). |
* |
* This hook is used only by atomic helpers, for symmetry with @disable. |
* Atomic drivers don't need to implement it if there's no need to |
* enable anything at the encoder level. To ensure that runtime PM handling |
* (using either DPMS or the new "ACTIVE" property) works |
* @enable must be the inverse of @disable for atomic drivers. |
*/ |
void (*enable)(struct drm_encoder *encoder); |
/** |
* @atomic_check: |
* |
* This callback is used to validate encoder state for atomic drivers. |
* Since the encoder is the object connecting the CRTC and connector it |
* gets passed both states, to be able to validate interactions and |
* update the CRTC to match what the encoder needs for the requested |
* connector. |
* |
* This function is used by the atomic helpers, but it is optional. |
* |
* NOTE: |
* |
* This function is called in the check phase of an atomic update. The |
* driver is not allowed to change anything outside of the free-standing |
* state objects passed-in or assembled in the overall &drm_atomic_state |
* update tracking structure. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the state or the transition can't be |
* supported, -ENOMEM on memory allocation failure and -EDEADLK if an |
* attempt to obtain another state object ran into a &drm_modeset_lock |
* deadlock. |
*/ |
int (*atomic_check)(struct drm_encoder *encoder, |
struct drm_crtc_state *crtc_state, |
struct drm_connector_state *conn_state); |
}; |
/** |
* drm_encoder_helper_add - sets the helper vtable for an encoder |
* @encoder: DRM encoder |
* @funcs: helper vtable to set for @encoder |
*/ |
static inline void drm_encoder_helper_add(struct drm_encoder *encoder, |
const struct drm_encoder_helper_funcs *funcs) |
{ |
encoder->helper_private = funcs; |
} |
/** |
* struct drm_connector_helper_funcs - helper operations for connectors |
* |
* These functions are used by the atomic and legacy modeset helpers and by the |
* probe helpers. |
*/ |
struct drm_connector_helper_funcs { |
/** |
* @get_modes: |
* |
* This function should fill in all modes currently valid for the sink |
* into the connector->probed_modes list. It should also update the |
* EDID property by calling drm_mode_connector_update_edid_property(). |
* |
* The usual way to implement this is to cache the EDID retrieved in the |
* probe callback somewhere in the driver-private connector structure. |
* In this function drivers then parse the modes in the EDID and add |
* them by calling drm_add_edid_modes(). But connectors that driver a |
* fixed panel can also manually add specific modes using |
* drm_mode_probed_add(). Drivers which manually add modes should also |
* make sure that the @display_info, @width_mm and @height_mm fields of the |
* struct #drm_connector are filled in. |
* |
* Virtual drivers that just want some standard VESA mode with a given |
* resolution can call drm_add_modes_noedid(), and mark the preferred |
* one using drm_set_preferred_mode(). |
* |
* Finally drivers that support audio probably want to update the ELD |
* data, too, using drm_edid_to_eld(). |
* |
* This function is only called after the ->detect() hook has indicated |
* that a sink is connected and when the EDID isn't overridden through |
* sysfs or the kernel commandline. |
* |
* This callback is used by the probe helpers in e.g. |
* drm_helper_probe_single_connector_modes(). |
* |
* RETURNS: |
* |
* The number of modes added by calling drm_mode_probed_add(). |
*/ |
int (*get_modes)(struct drm_connector *connector); |
/** |
* @mode_valid: |
* |
* Callback to validate a mode for a connector, irrespective of the |
* specific display configuration. |
* |
* This callback is used by the probe helpers to filter the mode list |
* (which is usually derived from the EDID data block from the sink). |
* See e.g. drm_helper_probe_single_connector_modes(). |
* |
* NOTE: |
* |
* This only filters the mode list supplied to userspace in the |
* GETCONNECOTR IOCTL. Userspace is free to create modes of its own and |
* ask the kernel to use them. It this case the atomic helpers or legacy |
* CRTC helpers will not call this function. Drivers therefore must |
* still fully validate any mode passed in in a modeset request. |
* |
* RETURNS: |
* |
* Either MODE_OK or one of the failure reasons in enum |
* &drm_mode_status. |
*/ |
enum drm_mode_status (*mode_valid)(struct drm_connector *connector, |
struct drm_display_mode *mode); |
/** |
* @best_encoder: |
* |
* This function should select the best encoder for the given connector. |
* |
* This function is used by both the atomic helpers (in the |
* drm_atomic_helper_check_modeset() function) and in the legacy CRTC |
* helpers. |
* |
* NOTE: |
* |
* In atomic drivers this function is called in the check phase of an |
* atomic update. The driver is not allowed to change or inspect |
* anything outside of arguments passed-in. Atomic drivers which need to |
* inspect dynamic configuration state should instead use |
* @atomic_best_encoder. |
* |
* RETURNS: |
* |
* Encoder that should be used for the given connector and connector |
* state, or NULL if no suitable encoder exists. Note that the helpers |
* will ensure that encoders aren't used twice, drivers should not check |
* for this. |
*/ |
struct drm_encoder *(*best_encoder)(struct drm_connector *connector); |
/** |
* @atomic_best_encoder: |
* |
* This is the atomic version of @best_encoder for atomic drivers which |
* need to select the best encoder depending upon the desired |
* configuration and can't select it statically. |
* |
* This function is used by drm_atomic_helper_check_modeset() and either |
* this or @best_encoder is required. |
* |
* NOTE: |
* |
* This function is called in the check phase of an atomic update. The |
* driver is not allowed to change anything outside of the free-standing |
* state objects passed-in or assembled in the overall &drm_atomic_state |
* update tracking structure. |
* |
* RETURNS: |
* |
* Encoder that should be used for the given connector and connector |
* state, or NULL if no suitable encoder exists. Note that the helpers |
* will ensure that encoders aren't used twice, drivers should not check |
* for this. |
*/ |
struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, |
struct drm_connector_state *connector_state); |
}; |
/** |
* drm_connector_helper_add - sets the helper vtable for a connector |
* @connector: DRM connector |
* @funcs: helper vtable to set for @connector |
*/ |
static inline void drm_connector_helper_add(struct drm_connector *connector, |
const struct drm_connector_helper_funcs *funcs) |
{ |
connector->helper_private = funcs; |
} |
/** |
* struct drm_plane_helper_funcs - helper operations for planes |
* |
* These functions are used by the atomic helpers and by the transitional plane |
* helpers. |
*/ |
struct drm_plane_helper_funcs { |
/** |
* @prepare_fb: |
* |
* This hook is to prepare a framebuffer for scanout by e.g. pinning |
* it's backing storage or relocating it into a contiguous block of |
* VRAM. Other possible preparatory work includes flushing caches. |
* |
* This function must not block for outstanding rendering, since it is |
* called in the context of the atomic IOCTL even for async commits to |
* be able to return any errors to userspace. Instead the recommended |
* way is to fill out the fence member of the passed-in |
* &drm_plane_state. If the driver doesn't support native fences then |
* equivalent functionality should be implemented through private |
* members in the plane structure. |
* |
* The helpers will call @cleanup_fb with matching arguments for every |
* successful call to this hook. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
* |
* RETURNS: |
* |
* 0 on success or one of the following negative error codes allowed by |
* the atomic_commit hook in &drm_mode_config_funcs. When using helpers |
* this callback is the only one which can fail an atomic commit, |
* everything else must complete successfully. |
*/ |
int (*prepare_fb)(struct drm_plane *plane, |
const struct drm_plane_state *new_state); |
/** |
* @cleanup_fb: |
* |
* This hook is called to clean up any resources allocated for the given |
* framebuffer and plane configuration in @prepare_fb. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
*/ |
void (*cleanup_fb)(struct drm_plane *plane, |
const struct drm_plane_state *old_state); |
/** |
* @atomic_check: |
* |
* Drivers should check plane specific constraints in this hook. |
* |
* When using drm_atomic_helper_check_planes() plane's ->atomic_check() |
* hooks are called before the ones for CRTCs, which allows drivers to |
* request shared resources that the CRTC controls here. For more |
* complicated dependencies the driver can call the provided check helpers |
* multiple times until the computed state has a final configuration and |
* everything has been checked. |
* |
* This function is also allowed to inspect any other object's state and |
* can add more state objects to the atomic commit if needed. Care must |
* be taken though to ensure that state check&compute functions for |
* these added states are all called, and derived state in other objects |
* all updated. Again the recommendation is to just call check helpers |
* until a maximal configuration is reached. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
* |
* NOTE: |
* |
* This function is called in the check phase of an atomic update. The |
* driver is not allowed to change anything outside of the free-standing |
* state objects passed-in or assembled in the overall &drm_atomic_state |
* update tracking structure. |
* |
* RETURNS: |
* |
* 0 on success, -EINVAL if the state or the transition can't be |
* supported, -ENOMEM on memory allocation failure and -EDEADLK if an |
* attempt to obtain another state object ran into a &drm_modeset_lock |
* deadlock. |
*/ |
int (*atomic_check)(struct drm_plane *plane, |
struct drm_plane_state *state); |
/** |
* @atomic_update: |
* |
* Drivers should use this function to update the plane state. This |
* hook is called in-between the ->atomic_begin() and |
* ->atomic_flush() of &drm_crtc_helper_funcs. |
* |
* Note that the power state of the display pipe when this function is |
* called depends upon the exact helpers and calling sequence the driver |
* has picked. See drm_atomic_commit_planes() for a discussion of the |
* tradeoffs and variants of plane commit helpers. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
*/ |
void (*atomic_update)(struct drm_plane *plane, |
struct drm_plane_state *old_state); |
/** |
* @atomic_disable: |
* |
* Drivers should use this function to unconditionally disable a plane. |
* This hook is called in-between the ->atomic_begin() and |
* ->atomic_flush() of &drm_crtc_helper_funcs. It is an alternative to |
* @atomic_update, which will be called for disabling planes, too, if |
* the @atomic_disable hook isn't implemented. |
* |
* This hook is also useful to disable planes in preparation of a modeset, |
* by calling drm_atomic_helper_disable_planes_on_crtc() from the |
* ->disable() hook in &drm_crtc_helper_funcs. |
* |
* Note that the power state of the display pipe when this function is |
* called depends upon the exact helpers and calling sequence the driver |
* has picked. See drm_atomic_commit_planes() for a discussion of the |
* tradeoffs and variants of plane commit helpers. |
* |
* This callback is used by the atomic modeset helpers and by the |
* transitional plane helpers, but it is optional. |
*/ |
void (*atomic_disable)(struct drm_plane *plane, |
struct drm_plane_state *old_state); |
}; |
/** |
* drm_plane_helper_add - sets the helper vtable for a plane |
* @plane: DRM plane |
* @funcs: helper vtable to set for @plane |
*/ |
static inline void drm_plane_helper_add(struct drm_plane *plane, |
const struct drm_plane_helper_funcs *funcs) |
{ |
plane->helper_private = funcs; |
} |
#endif |
/drivers/include/drm/drm_modeset_lock.h |
---|
138,7 → 138,7 |
struct drm_modeset_acquire_ctx * |
drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc); |
int drm_modeset_lock_all_crtcs(struct drm_device *dev, |
int drm_modeset_lock_all_ctx(struct drm_device *dev, |
struct drm_modeset_acquire_ctx *ctx); |
#endif /* DRM_MODESET_LOCK_H_ */ |
/drivers/include/drm/drm_plane_helper.h |
---|
26,6 → 26,7 |
#include <drm/drm_rect.h> |
#include <drm/drm_crtc.h> |
#include <drm/drm_modeset_helper_vtables.h> |
/* |
* Drivers that don't allow primary plane scaling may pass this macro in place |
36,46 → 37,9 |
*/ |
#define DRM_PLANE_HELPER_NO_SCALING (1<<16) |
/** |
* DOC: plane helpers |
* |
* Helper functions to assist with creation and handling of CRTC primary |
* planes. |
*/ |
int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
const struct drm_crtc_funcs *funcs); |
/** |
* drm_plane_helper_funcs - helper operations for CRTCs |
* @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 (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, |
const struct drm_plane_state *new_state); |
void (*cleanup_fb)(struct drm_plane *plane, |
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 = funcs; |
} |
int drm_plane_helper_check_update(struct drm_plane *plane, |
struct drm_crtc *crtc, |
struct drm_framebuffer *fb, |
/drivers/include/drm/drm_rect.h |
---|
162,7 → 162,8 |
int drm_rect_calc_vscale_relaxed(struct drm_rect *src, |
struct drm_rect *dst, |
int min_vscale, int max_vscale); |
void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point); |
void drm_rect_debug_print(const char *prefix, |
const struct drm_rect *r, bool fixed_point); |
void drm_rect_rotate(struct drm_rect *r, |
int width, int height, |
unsigned int rotation); |
/drivers/include/drm/i915_component.h |
---|
31,47 → 31,94 |
#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 - Ops implemented by i915 driver, called by hda driver |
*/ |
struct i915_audio_component_ops { |
/** |
* @owner: i915 module |
*/ |
struct module *owner; |
/** |
* @get_power: get the POWER_DOMAIN_AUDIO power well |
* |
* Request the power well to be turned on. |
*/ |
void (*get_power)(struct device *); |
/** |
* @put_power: put the POWER_DOMAIN_AUDIO power well |
* |
* Allow the power well to be turned off. |
*/ |
void (*put_power)(struct device *); |
/** |
* @codec_wake_override: Enable/disable codec wake signal |
*/ |
void (*codec_wake_override)(struct device *, bool enable); |
/** |
* @get_cdclk_freq: Get the Core Display Clock in kHz |
*/ |
int (*get_cdclk_freq)(struct device *); |
/** |
* @sync_audio_rate: set n/cts based on the sample rate |
* |
* Called from audio driver. After audio driver sets the |
* sample rate, it will call this function to set n/cts |
*/ |
int (*sync_audio_rate)(struct device *, int port, int rate); |
/** |
* @get_eld: fill the audio state and ELD bytes for the given port |
* |
* Called from audio driver to get the HDMI/DP audio state of the given |
* digital port, and also fetch ELD bytes to the given pointer. |
* |
* It returns the byte size of the original ELD (not the actually |
* copied size), zero for an invalid ELD, or a negative error code. |
* |
* Note that the returned size may be over @max_bytes. Then it |
* implies that only a part of ELD has been copied to the buffer. |
*/ |
int (*get_eld)(struct device *, int port, bool *enabled, |
unsigned char *buf, int max_bytes); |
}; |
/** |
* struct i915_audio_component_audio_ops - Ops implemented by hda driver, called by i915 driver |
*/ |
struct i915_audio_component_audio_ops { |
/** |
* @audio_ptr: Pointer to be used in call to pin_eld_notify |
*/ |
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) |
* @pin_eld_notify: Notify the HDA driver that pin sense and/or ELD information has changed |
* |
* Called when the i915 driver has set up audio pipeline or has just |
* begun to tear it down. This allows the HDA driver to update its |
* status accordingly (even when the HDA controller is in power save |
* mode). |
*/ |
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 - Used for direct communication between i915 and hda drivers |
*/ |
struct i915_audio_component { |
/** |
* @dev: i915 device, used as parameter for ops |
*/ |
struct device *dev; |
/** |
* @aud_sample_rate: the array of audio sample rate per port |
*/ |
int aud_sample_rate[MAX_PORTS]; |
/** |
* @ops: Ops implemented by i915 driver, called by hda driver |
*/ |
const struct i915_audio_component_ops *ops; |
/** |
* @audio_ops: Ops implemented by hda driver, called by i915 driver |
*/ |
const struct i915_audio_component_audio_ops *audio_ops; |
}; |
/drivers/include/drm/i915_pciids.h |
---|
277,22 → 277,61 |
INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ |
#define INTEL_SKL_GT3_IDS(info) \ |
INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ |
INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ \ |
INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ |
#define INTEL_SKL_GT4_IDS(info) \ |
INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \ |
INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \ |
INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \ |
INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4 */ |
#define INTEL_SKL_IDS(info) \ |
INTEL_SKL_GT1_IDS(info), \ |
INTEL_SKL_GT2_IDS(info), \ |
INTEL_SKL_GT3_IDS(info) |
INTEL_SKL_GT3_IDS(info), \ |
INTEL_SKL_GT4_IDS(info) |
#define INTEL_BXT_IDS(info) \ |
INTEL_VGA_DEVICE(0x0A84, info), \ |
INTEL_VGA_DEVICE(0x1A84, info), \ |
INTEL_VGA_DEVICE(0x1A85, info), \ |
INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \ |
INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */ |
INTEL_VGA_DEVICE(0x5A84, info) |
#define INTEL_KBL_GT1_IDS(info) \ |
INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \ |
INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \ |
INTEL_VGA_DEVICE(0x5917, info), /* DT GT1.5 */ \ |
INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \ |
INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \ |
INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \ |
INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \ |
INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */ |
#define INTEL_KBL_GT2_IDS(info) \ |
INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \ |
INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \ |
INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \ |
INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \ |
INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \ |
INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \ |
INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */ |
#define INTEL_KBL_GT3_IDS(info) \ |
INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \ |
INTEL_VGA_DEVICE(0x592B, info), /* Halo GT3 */ \ |
INTEL_VGA_DEVICE(0x592A, info) /* SRV GT3 */ |
#define INTEL_KBL_GT4_IDS(info) \ |
INTEL_VGA_DEVICE(0x5932, info), /* DT GT4 */ \ |
INTEL_VGA_DEVICE(0x593B, info), /* Halo GT4 */ \ |
INTEL_VGA_DEVICE(0x593A, info), /* SRV GT4 */ \ |
INTEL_VGA_DEVICE(0x593D, info) /* WKS GT4 */ |
#define INTEL_KBL_IDS(info) \ |
INTEL_KBL_GT1_IDS(info), \ |
INTEL_KBL_GT2_IDS(info), \ |
INTEL_KBL_GT3_IDS(info), \ |
INTEL_KBL_GT4_IDS(info) |
#endif /* _I915_PCIIDS_H */ |
/drivers/include/drm/ttm/ttm_bo_api.h |
---|
316,21 → 316,7 |
*/ |
extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, |
bool interruptible, bool no_wait); |
/** |
* ttm_bo_mem_compat - Check if proposed placement is compatible with a bo |
* |
* @placement: Return immediately if buffer is busy. |
* @mem: The struct ttm_mem_reg indicating the region where the bo resides |
* @new_flags: Describes compatible placement found |
* |
* Returns true if the placement is compatible |
*/ |
extern bool ttm_bo_mem_compat(struct ttm_placement *placement, |
struct ttm_mem_reg *mem, |
uint32_t *new_flags); |
/** |
* ttm_bo_validate |
* |
* @bo: The buffer object. |
397,6 → 383,16 |
*/ |
extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); |
/** |
* ttm_bo_move_to_lru_tail |
* |
* @bo: The buffer object. |
* |
* Move this BO to the tail of all lru lists used to lookup and reserve an |
* object. This function must be called with struct ttm_bo_global::lru_lock |
* held, and is used to make a BO less likely to be considered for eviction. |
*/ |
extern void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); |
/** |
* ttm_bo_lock_delayed_workqueue |
/drivers/include/drm/ttm/ttm_bo_driver.h |
---|
826,10 → 826,10 |
* reserved, the validation sequence is checked against the validation |
* sequence of the process currently reserving the buffer, |
* and if the current validation sequence is greater than that of the process |
* holding the reservation, the function returns -EAGAIN. Otherwise it sleeps |
* holding the reservation, the function returns -EDEADLK. Otherwise it sleeps |
* waiting for the buffer to become unreserved, after which it retries |
* reserving. |
* The caller should, when receiving an -EAGAIN error |
* The caller should, when receiving an -EDEADLK error |
* release all its buffer reservations, wait for @bo to become unreserved, and |
* then rerun the validation with the same validation sequence. This procedure |
* will always guarantee that the process with the lowest validation sequence |