xref: /dragonfly/sys/dev/drm/include/drm/drm_encoder.h (revision 3f2dd94a)
11dedbd3bSFrançois Tigeot /*
21dedbd3bSFrançois Tigeot  * Copyright (c) 2016 Intel Corporation
31dedbd3bSFrançois Tigeot  *
41dedbd3bSFrançois Tigeot  * Permission to use, copy, modify, distribute, and sell this software and its
51dedbd3bSFrançois Tigeot  * documentation for any purpose is hereby granted without fee, provided that
61dedbd3bSFrançois Tigeot  * the above copyright notice appear in all copies and that both that copyright
71dedbd3bSFrançois Tigeot  * notice and this permission notice appear in supporting documentation, and
81dedbd3bSFrançois Tigeot  * that the name of the copyright holders not be used in advertising or
91dedbd3bSFrançois Tigeot  * publicity pertaining to distribution of the software without specific,
101dedbd3bSFrançois Tigeot  * written prior permission.  The copyright holders make no representations
111dedbd3bSFrançois Tigeot  * about the suitability of this software for any purpose.  It is provided "as
121dedbd3bSFrançois Tigeot  * is" without express or implied warranty.
131dedbd3bSFrançois Tigeot  *
141dedbd3bSFrançois Tigeot  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
151dedbd3bSFrançois Tigeot  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
161dedbd3bSFrançois Tigeot  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
171dedbd3bSFrançois Tigeot  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
181dedbd3bSFrançois Tigeot  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
191dedbd3bSFrançois Tigeot  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
201dedbd3bSFrançois Tigeot  * OF THIS SOFTWARE.
211dedbd3bSFrançois Tigeot  */
221dedbd3bSFrançois Tigeot 
231dedbd3bSFrançois Tigeot #ifndef __DRM_ENCODER_H__
241dedbd3bSFrançois Tigeot #define __DRM_ENCODER_H__
251dedbd3bSFrançois Tigeot 
261dedbd3bSFrançois Tigeot #include <linux/list.h>
271dedbd3bSFrançois Tigeot #include <linux/ctype.h>
28a85cb24fSFrançois Tigeot #include <drm/drm_crtc.h>
29a85cb24fSFrançois Tigeot #include <drm/drm_mode.h>
301dedbd3bSFrançois Tigeot #include <drm/drm_mode_object.h>
311dedbd3bSFrançois Tigeot 
32a85cb24fSFrançois Tigeot struct drm_encoder;
33a85cb24fSFrançois Tigeot 
341dedbd3bSFrançois Tigeot /**
351dedbd3bSFrançois Tigeot  * struct drm_encoder_funcs - encoder controls
361dedbd3bSFrançois Tigeot  *
371dedbd3bSFrançois Tigeot  * Encoders sit between CRTCs and connectors.
381dedbd3bSFrançois Tigeot  */
391dedbd3bSFrançois Tigeot struct drm_encoder_funcs {
401dedbd3bSFrançois Tigeot 	/**
411dedbd3bSFrançois Tigeot 	 * @reset:
421dedbd3bSFrançois Tigeot 	 *
431dedbd3bSFrançois Tigeot 	 * Reset encoder hardware and software state to off. This function isn't
441dedbd3bSFrançois Tigeot 	 * called by the core directly, only through drm_mode_config_reset().
451dedbd3bSFrançois Tigeot 	 * It's not a helper hook only for historical reasons.
461dedbd3bSFrançois Tigeot 	 */
471dedbd3bSFrançois Tigeot 	void (*reset)(struct drm_encoder *encoder);
481dedbd3bSFrançois Tigeot 
491dedbd3bSFrançois Tigeot 	/**
501dedbd3bSFrançois Tigeot 	 * @destroy:
511dedbd3bSFrançois Tigeot 	 *
521dedbd3bSFrançois Tigeot 	 * Clean up encoder resources. This is only called at driver unload time
531dedbd3bSFrançois Tigeot 	 * through drm_mode_config_cleanup() since an encoder cannot be
541dedbd3bSFrançois Tigeot 	 * hotplugged in DRM.
551dedbd3bSFrançois Tigeot 	 */
561dedbd3bSFrançois Tigeot 	void (*destroy)(struct drm_encoder *encoder);
571dedbd3bSFrançois Tigeot 
581dedbd3bSFrançois Tigeot 	/**
591dedbd3bSFrançois Tigeot 	 * @late_register:
601dedbd3bSFrançois Tigeot 	 *
611dedbd3bSFrançois Tigeot 	 * This optional hook can be used to register additional userspace
621dedbd3bSFrançois Tigeot 	 * interfaces attached to the encoder like debugfs interfaces.
631dedbd3bSFrançois Tigeot 	 * It is called late in the driver load sequence from drm_dev_register().
641dedbd3bSFrançois Tigeot 	 * Everything added from this callback should be unregistered in
651dedbd3bSFrançois Tigeot 	 * the early_unregister callback.
661dedbd3bSFrançois Tigeot 	 *
671dedbd3bSFrançois Tigeot 	 * Returns:
681dedbd3bSFrançois Tigeot 	 *
691dedbd3bSFrançois Tigeot 	 * 0 on success, or a negative error code on failure.
701dedbd3bSFrançois Tigeot 	 */
711dedbd3bSFrançois Tigeot 	int (*late_register)(struct drm_encoder *encoder);
721dedbd3bSFrançois Tigeot 
731dedbd3bSFrançois Tigeot 	/**
741dedbd3bSFrançois Tigeot 	 * @early_unregister:
751dedbd3bSFrançois Tigeot 	 *
761dedbd3bSFrançois Tigeot 	 * This optional hook should be used to unregister the additional
771dedbd3bSFrançois Tigeot 	 * userspace interfaces attached to the encoder from
78a85cb24fSFrançois Tigeot 	 * @late_register. It is called from drm_dev_unregister(),
791dedbd3bSFrançois Tigeot 	 * early in the driver unload sequence to disable userspace access
801dedbd3bSFrançois Tigeot 	 * before data structures are torndown.
811dedbd3bSFrançois Tigeot 	 */
821dedbd3bSFrançois Tigeot 	void (*early_unregister)(struct drm_encoder *encoder);
831dedbd3bSFrançois Tigeot };
841dedbd3bSFrançois Tigeot 
851dedbd3bSFrançois Tigeot /**
861dedbd3bSFrançois Tigeot  * struct drm_encoder - central DRM encoder structure
871dedbd3bSFrançois Tigeot  * @dev: parent DRM device
881dedbd3bSFrançois Tigeot  * @head: list management
891dedbd3bSFrançois Tigeot  * @base: base KMS object
901dedbd3bSFrançois Tigeot  * @name: human readable name, can be overwritten by the driver
911dedbd3bSFrançois Tigeot  * @crtc: currently bound CRTC
921dedbd3bSFrançois Tigeot  * @bridge: bridge associated to the encoder
931dedbd3bSFrançois Tigeot  * @funcs: control functions
941dedbd3bSFrançois Tigeot  * @helper_private: mid-layer private data
951dedbd3bSFrançois Tigeot  *
961dedbd3bSFrançois Tigeot  * CRTCs drive pixels to encoders, which convert them into signals
971dedbd3bSFrançois Tigeot  * appropriate for a given connector or set of connectors.
981dedbd3bSFrançois Tigeot  */
991dedbd3bSFrançois Tigeot struct drm_encoder {
1001dedbd3bSFrançois Tigeot 	struct drm_device *dev;
1011dedbd3bSFrançois Tigeot 	struct list_head head;
1021dedbd3bSFrançois Tigeot 
1031dedbd3bSFrançois Tigeot 	struct drm_mode_object base;
1041dedbd3bSFrançois Tigeot 	char *name;
1051dedbd3bSFrançois Tigeot 	/**
1061dedbd3bSFrançois Tigeot 	 * @encoder_type:
1071dedbd3bSFrançois Tigeot 	 *
1081dedbd3bSFrançois Tigeot 	 * One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following
1091dedbd3bSFrançois Tigeot 	 * encoder types are defined thus far:
1101dedbd3bSFrançois Tigeot 	 *
1111dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A.
1121dedbd3bSFrançois Tigeot 	 *
1131dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort.
1141dedbd3bSFrançois Tigeot 	 *
1151dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_LVDS for display panels, or in general any panel
1161dedbd3bSFrançois Tigeot 	 *   with a proprietary parallel connector.
1171dedbd3bSFrançois Tigeot 	 *
1181dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
1191dedbd3bSFrançois Tigeot 	 *   Component, SCART).
1201dedbd3bSFrançois Tigeot 	 *
1211dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
1221dedbd3bSFrançois Tigeot 	 *
1231dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_DSI for panels connected using the DSI serial bus.
1241dedbd3bSFrançois Tigeot 	 *
1251dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_DPI for panels connected using the DPI parallel
1261dedbd3bSFrançois Tigeot 	 *   bus.
1271dedbd3bSFrançois Tigeot 	 *
1281dedbd3bSFrançois Tigeot 	 * - DRM_MODE_ENCODER_DPMST for special fake encoders used to allow
1291dedbd3bSFrançois Tigeot 	 *   mutliple DP MST streams to share one physical encoder.
1301dedbd3bSFrançois Tigeot 	 */
1311dedbd3bSFrançois Tigeot 	int encoder_type;
1321dedbd3bSFrançois Tigeot 
1331dedbd3bSFrançois Tigeot 	/**
1341dedbd3bSFrançois Tigeot 	 * @index: Position inside the mode_config.list, can be used as an array
1351dedbd3bSFrançois Tigeot 	 * index. It is invariant over the lifetime of the encoder.
1361dedbd3bSFrançois Tigeot 	 */
1371dedbd3bSFrançois Tigeot 	unsigned index;
1381dedbd3bSFrançois Tigeot 
1391dedbd3bSFrançois Tigeot 	/**
1401dedbd3bSFrançois Tigeot 	 * @possible_crtcs: Bitmask of potential CRTC bindings, using
1411dedbd3bSFrançois Tigeot 	 * drm_crtc_index() as the index into the bitfield. The driver must set
1421dedbd3bSFrançois Tigeot 	 * the bits for all &drm_crtc objects this encoder can be connected to
1431dedbd3bSFrançois Tigeot 	 * before calling drm_encoder_init().
1441dedbd3bSFrançois Tigeot 	 *
1451dedbd3bSFrançois Tigeot 	 * In reality almost every driver gets this wrong.
1461dedbd3bSFrançois Tigeot 	 *
1471dedbd3bSFrançois Tigeot 	 * Note that since CRTC objects can't be hotplugged the assigned indices
1481dedbd3bSFrançois Tigeot 	 * are stable and hence known before registering all objects.
1491dedbd3bSFrançois Tigeot 	 */
1501dedbd3bSFrançois Tigeot 	uint32_t possible_crtcs;
1511dedbd3bSFrançois Tigeot 
1521dedbd3bSFrançois Tigeot 	/**
1531dedbd3bSFrançois Tigeot 	 * @possible_clones: Bitmask of potential sibling encoders for cloning,
1541dedbd3bSFrançois Tigeot 	 * using drm_encoder_index() as the index into the bitfield. The driver
1551dedbd3bSFrançois Tigeot 	 * must set the bits for all &drm_encoder objects which can clone a
1561dedbd3bSFrançois Tigeot 	 * &drm_crtc together with this encoder before calling
1571dedbd3bSFrançois Tigeot 	 * drm_encoder_init(). Drivers should set the bit representing the
1581dedbd3bSFrançois Tigeot 	 * encoder itself, too. Cloning bits should be set such that when two
1591dedbd3bSFrançois Tigeot 	 * encoders can be used in a cloned configuration, they both should have
1601dedbd3bSFrançois Tigeot 	 * each another bits set.
1611dedbd3bSFrançois Tigeot 	 *
1621dedbd3bSFrançois Tigeot 	 * In reality almost every driver gets this wrong.
1631dedbd3bSFrançois Tigeot 	 *
1641dedbd3bSFrançois Tigeot 	 * Note that since encoder objects can't be hotplugged the assigned indices
1651dedbd3bSFrançois Tigeot 	 * are stable and hence known before registering all objects.
1661dedbd3bSFrançois Tigeot 	 */
1671dedbd3bSFrançois Tigeot 	uint32_t possible_clones;
1681dedbd3bSFrançois Tigeot 
1691dedbd3bSFrançois Tigeot 	struct drm_crtc *crtc;
1701dedbd3bSFrançois Tigeot 	struct drm_bridge *bridge;
1711dedbd3bSFrançois Tigeot 	const struct drm_encoder_funcs *funcs;
1721dedbd3bSFrançois Tigeot 	const struct drm_encoder_helper_funcs *helper_private;
1731dedbd3bSFrançois Tigeot };
1741dedbd3bSFrançois Tigeot 
1751dedbd3bSFrançois Tigeot #define obj_to_encoder(x) container_of(x, struct drm_encoder, base)
1761dedbd3bSFrançois Tigeot 
1771dedbd3bSFrançois Tigeot int drm_encoder_init(struct drm_device *dev,
1781dedbd3bSFrançois Tigeot 		     struct drm_encoder *encoder,
1791dedbd3bSFrançois Tigeot 		     const struct drm_encoder_funcs *funcs,
1801dedbd3bSFrançois Tigeot 		     int encoder_type, const char *name, ...);
1811dedbd3bSFrançois Tigeot 
1821dedbd3bSFrançois Tigeot /**
1831dedbd3bSFrançois Tigeot  * drm_encoder_index - find the index of a registered encoder
1841dedbd3bSFrançois Tigeot  * @encoder: encoder to find index for
1851dedbd3bSFrançois Tigeot  *
1861dedbd3bSFrançois Tigeot  * Given a registered encoder, return the index of that encoder within a DRM
1871dedbd3bSFrançois Tigeot  * device's list of encoders.
1881dedbd3bSFrançois Tigeot  */
drm_encoder_index(struct drm_encoder * encoder)1891dedbd3bSFrançois Tigeot static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
1901dedbd3bSFrançois Tigeot {
1911dedbd3bSFrançois Tigeot 	return encoder->index;
1921dedbd3bSFrançois Tigeot }
1931dedbd3bSFrançois Tigeot 
1941dedbd3bSFrançois Tigeot /**
1951dedbd3bSFrançois Tigeot  * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
1961dedbd3bSFrançois Tigeot  * @encoder: encoder to test
1971dedbd3bSFrançois Tigeot  * @crtc: crtc to test
1981dedbd3bSFrançois Tigeot  *
1991dedbd3bSFrançois Tigeot  * Returns false if @encoder can't be driven by @crtc, true otherwise.
2001dedbd3bSFrançois Tigeot  */
drm_encoder_crtc_ok(struct drm_encoder * encoder,struct drm_crtc * crtc)2011dedbd3bSFrançois Tigeot static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
2021dedbd3bSFrançois Tigeot 				       struct drm_crtc *crtc)
2031dedbd3bSFrançois Tigeot {
2041dedbd3bSFrançois Tigeot 	return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
2051dedbd3bSFrançois Tigeot }
2061dedbd3bSFrançois Tigeot 
2071dedbd3bSFrançois Tigeot /**
2081dedbd3bSFrançois Tigeot  * drm_encoder_find - find a &drm_encoder
2091dedbd3bSFrançois Tigeot  * @dev: DRM device
210*3f2dd94aSFrançois Tigeot  * @file_priv: drm file to check for lease against.
2111dedbd3bSFrançois Tigeot  * @id: encoder id
2121dedbd3bSFrançois Tigeot  *
2131dedbd3bSFrançois Tigeot  * Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around
2141dedbd3bSFrançois Tigeot  * drm_mode_object_find().
2151dedbd3bSFrançois Tigeot  */
drm_encoder_find(struct drm_device * dev,struct drm_file * file_priv,uint32_t id)2161dedbd3bSFrançois Tigeot static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
217*3f2dd94aSFrançois Tigeot 						   struct drm_file *file_priv,
2181dedbd3bSFrançois Tigeot 						   uint32_t id)
2191dedbd3bSFrançois Tigeot {
2201dedbd3bSFrançois Tigeot 	struct drm_mode_object *mo;
2211dedbd3bSFrançois Tigeot 
222*3f2dd94aSFrançois Tigeot 	mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER);
2231dedbd3bSFrançois Tigeot 
2241dedbd3bSFrançois Tigeot 	return mo ? obj_to_encoder(mo) : NULL;
2251dedbd3bSFrançois Tigeot }
2261dedbd3bSFrançois Tigeot 
2271dedbd3bSFrançois Tigeot void drm_encoder_cleanup(struct drm_encoder *encoder);
2281dedbd3bSFrançois Tigeot 
2291dedbd3bSFrançois Tigeot /**
2301dedbd3bSFrançois Tigeot  * drm_for_each_encoder_mask - iterate over encoders specified by bitmask
2311dedbd3bSFrançois Tigeot  * @encoder: the loop cursor
2321dedbd3bSFrançois Tigeot  * @dev: the DRM device
2331dedbd3bSFrançois Tigeot  * @encoder_mask: bitmask of encoder indices
2341dedbd3bSFrançois Tigeot  *
2351dedbd3bSFrançois Tigeot  * Iterate over all encoders specified by bitmask.
2361dedbd3bSFrançois Tigeot  */
2371dedbd3bSFrançois Tigeot #define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \
2381dedbd3bSFrançois Tigeot 	list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \
2391dedbd3bSFrançois Tigeot 		for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder)))
2401dedbd3bSFrançois Tigeot 
2411dedbd3bSFrançois Tigeot /**
2421dedbd3bSFrançois Tigeot  * drm_for_each_encoder - iterate over all encoders
2431dedbd3bSFrançois Tigeot  * @encoder: the loop cursor
2441dedbd3bSFrançois Tigeot  * @dev: the DRM device
2451dedbd3bSFrançois Tigeot  *
2461dedbd3bSFrançois Tigeot  * Iterate over all encoders of @dev.
2471dedbd3bSFrançois Tigeot  */
2481dedbd3bSFrançois Tigeot #define drm_for_each_encoder(encoder, dev) \
2491dedbd3bSFrançois Tigeot 	list_for_each_entry(encoder, &(dev)->mode_config.encoder_list, head)
2501dedbd3bSFrançois Tigeot 
2511dedbd3bSFrançois Tigeot #endif
252