Commit e03e6de0 authored by Daniel Vetter's avatar Daniel Vetter

drm/doc: Polish kerneldoc for encoders

- Move missing bits into struct drm_encoder docs.
- Explain that encoders are 95% internal and only 5% uapi, and that in
  general the uapi part is broken.
- Remove verbose comments for functions not exposed to drivers.

v2: Review from Archit:
- Appease checkpatch in the moved code.
- Make it clearer that bridges are not exposed to userspace.
Reviewed-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160829082757.17913-2-daniel.vetter@ffwll.ch
parent 321a95ae
...@@ -128,6 +128,12 @@ Connector Functions Reference ...@@ -128,6 +128,12 @@ Connector Functions Reference
Encoder Abstraction Encoder Abstraction
=================== ===================
.. kernel-doc:: drivers/gpu/drm/drm_encoder.c
:doc: overview
Encoder Functions Reference
---------------------------
.. kernel-doc:: include/drm/drm_encoder.h .. kernel-doc:: include/drm/drm_encoder.h
:internal: :internal:
...@@ -207,46 +213,6 @@ future); drivers that do not wish to provide special handling for ...@@ -207,46 +213,6 @@ future); drivers that do not wish to provide special handling for
primary planes may make use of the helper functions described in ? to primary planes may make use of the helper functions described in ? to
create and register a primary plane with standard capabilities. create and register a primary plane with standard capabilities.
Encoders (:c:type:`struct drm_encoder <drm_encoder>`)
-----------------------------------------------------
An encoder takes pixel data from a CRTC and converts it to a format
suitable for any attached connectors. On some devices, it may be
possible to have a CRTC send data to more than one encoder. In that
case, both encoders would receive data from the same scanout buffer,
resulting in a "cloned" display configuration across the connectors
attached to each encoder.
Encoder Initialization
~~~~~~~~~~~~~~~~~~~~~~
As for CRTCs, a KMS driver must create, initialize and register at least
one :c:type:`struct drm_encoder <drm_encoder>` instance. The
instance is allocated and zeroed by the driver, possibly as part of a
larger structure.
Drivers must initialize the :c:type:`struct drm_encoder
<drm_encoder>` possible_crtcs and possible_clones fields before
registering the encoder. Both fields are bitmasks of respectively the
CRTCs that the encoder can be connected to, and sibling encoders
candidate for cloning.
After being initialized, the encoder must be registered with a call to
:c:func:`drm_encoder_init()`. The function takes a pointer to the
encoder functions and an encoder type. Supported types are
- DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A
- DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort
- DRM_MODE_ENCODER_LVDS for display panels
- DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
Component, SCART)
- DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
Encoders must be attached to a CRTC to be used. DRM drivers leave
encoders unattached at initialization time. Applications (or the fbdev
compatibility layer when implemented) are responsible for attaching the
encoders they want to use to a CRTC.
Cleanup Cleanup
------- -------
......
...@@ -26,6 +26,30 @@ ...@@ -26,6 +26,30 @@
#include "drm_crtc_internal.h" #include "drm_crtc_internal.h"
/**
* DOC: overview
*
* Encoders represent the connecting element between the CRTC (as the overall
* pixel pipeline, represented by struct &drm_crtc) and the connectors (as the
* generic sink entity, represented by struct &drm_connector). Encoders are
* objects exposed to userspace, originally to allow userspace to infer cloning
* and connector/CRTC restrictions. Unfortunately almost all drivers get this
* wrong, making the uabi pretty much useless. On top of that the exposed
* restrictions are too simple for todays hardware, and the recommend way to
* infer restrictions is by using the DRM_MODE_ATOMIC_TEST_ONLY flag for the
* atomic IOCTL.
*
* Otherwise encoders aren't used in the uapi at all (any modeset request from
* userspace directly connects a connector with a CRTC), drivers are therefore
* free to use them however they wish. Modeset helper libraries make strong use
* of encoders to facilitate code sharing. But for more complex settings it is
* usually better to move shared code into a separate &drm_bridge. Compared to
* encoders bridges also have the benefit of not being purely an internal
* abstraction since they are not exposed to userspace at all.
*
* Encoders are initialized with drm_encoder_init() and cleaned up using
* drm_encoder_cleanup().
*/
static const struct drm_prop_enum_list drm_encoder_enum_list[] = { static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
{ DRM_MODE_ENCODER_NONE, "None" }, { DRM_MODE_ENCODER_NONE, "None" },
{ DRM_MODE_ENCODER_DAC, "DAC" }, { DRM_MODE_ENCODER_DAC, "DAC" },
...@@ -71,16 +95,17 @@ void drm_encoder_unregister_all(struct drm_device *dev) ...@@ -71,16 +95,17 @@ void drm_encoder_unregister_all(struct drm_device *dev)
* @encoder_type: user visible type of the encoder * @encoder_type: user visible type of the encoder
* @name: printf style format string for the encoder name, or NULL for default name * @name: printf style format string for the encoder name, or NULL for default name
* *
* Initialises a preallocated encoder. Encoder should be * Initialises a preallocated encoder. Encoder should be subclassed as part of
* subclassed as part of driver encoder objects. * driver encoder objects. At driver unload time drm_encoder_cleanup() should be
* called from the driver's destroy hook in &drm_encoder_funcs.
* *
* Returns: * Returns:
* Zero on success, error code on failure. * Zero on success, error code on failure.
*/ */
int drm_encoder_init(struct drm_device *dev, int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder, struct drm_encoder *encoder,
const struct drm_encoder_funcs *funcs, const struct drm_encoder_funcs *funcs,
int encoder_type, const char *name, ...) int encoder_type, const char *name, ...)
{ {
int ret; int ret;
...@@ -176,19 +201,6 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder) ...@@ -176,19 +201,6 @@ static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
return encoder->crtc; return encoder->crtc;
} }
/**
* drm_mode_getencoder - get encoder configuration
* @dev: drm device for the ioctl
* @data: data pointer for the ioctl
* @file_priv: drm file for the ioctl call
*
* Construct a encoder configuration structure to return to the user.
*
* Called by the user via ioctl.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_getencoder(struct drm_device *dev, void *data, int drm_mode_getencoder(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
......
...@@ -84,9 +84,6 @@ struct drm_encoder_funcs { ...@@ -84,9 +84,6 @@ struct drm_encoder_funcs {
* @head: list management * @head: list management
* @base: base KMS object * @base: base KMS object
* @name: human readable name, can be overwritten by the driver * @name: human readable name, can be overwritten by the driver
* @encoder_type: one of the DRM_MODE_ENCODER_<foo> types in drm_mode.h
* @possible_crtcs: bitmask of potential CRTC bindings
* @possible_clones: bitmask of potential sibling encoders for cloning
* @crtc: currently bound CRTC * @crtc: currently bound CRTC
* @bridge: bridge associated to the encoder * @bridge: bridge associated to the encoder
* @funcs: control functions * @funcs: control functions
...@@ -101,6 +98,32 @@ struct drm_encoder { ...@@ -101,6 +98,32 @@ struct drm_encoder {
struct drm_mode_object base; struct drm_mode_object base;
char *name; char *name;
/**
* @encoder_type:
*
* One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following
* encoder types are defined thus far:
*
* - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A.
*
* - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort.
*
* - DRM_MODE_ENCODER_LVDS for display panels, or in general any panel
* with a proprietary parallel connector.
*
* - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
* Component, SCART).
*
* - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
*
* - DRM_MODE_ENCODER_DSI for panels connected using the DSI serial bus.
*
* - DRM_MODE_ENCODER_DPI for panels connected using the DPI parallel
* bus.
*
* - DRM_MODE_ENCODER_DPMST for special fake encoders used to allow
* mutliple DP MST streams to share one physical encoder.
*/
int encoder_type; int encoder_type;
/** /**
...@@ -109,7 +132,34 @@ struct drm_encoder { ...@@ -109,7 +132,34 @@ struct drm_encoder {
*/ */
unsigned index; unsigned index;
/**
* @possible_crtcs: Bitmask of potential CRTC bindings, using
* drm_crtc_index() as the index into the bitfield. The driver must set
* the bits for all &drm_crtc objects this encoder can be connected to
* before calling drm_encoder_init().
*
* In reality almost every driver gets this wrong.
*
* Note that since CRTC objects can't be hotplugged the assigned indices
* are stable and hence known before registering all objects.
*/
uint32_t possible_crtcs; uint32_t possible_crtcs;
/**
* @possible_clones: Bitmask of potential sibling encoders for cloning,
* using drm_encoder_index() as the index into the bitfield. The driver
* must set the bits for all &drm_encoder objects which can clone a
* &drm_crtc together with this encoder before calling
* drm_encoder_init(). Drivers should set the bit representing the
* encoder itself, too. Cloning bits should be set such that when two
* encoders can be used in a cloned configuration, they both should have
* each another bits set.
*
* In reality almost every driver gets this wrong.
*
* Note that since encoder objects can't be hotplugged the assigned indices
* are stable and hence known before registering all objects.
*/
uint32_t possible_clones; uint32_t possible_clones;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -146,7 +196,7 @@ static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc); ...@@ -146,7 +196,7 @@ static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc);
* @encoder: encoder to test * @encoder: encoder to test
* @crtc: crtc to test * @crtc: crtc to test
* *
* Return false if @encoder can't be driven by @crtc, true otherwise. * Returns false if @encoder can't be driven by @crtc, true otherwise.
*/ */
static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc) struct drm_crtc *crtc)
...@@ -154,11 +204,21 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder, ...@@ -154,11 +204,21 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
return !!(encoder->possible_crtcs & drm_crtc_mask(crtc)); return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
} }
/**
* drm_encoder_find - find a &drm_encoder
* @dev: DRM device
* @id: encoder id
*
* Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around
* drm_mode_object_find().
*/
static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev, static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
uint32_t id) uint32_t id)
{ {
struct drm_mode_object *mo; struct drm_mode_object *mo;
mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
return mo ? obj_to_encoder(mo) : NULL; return mo ? obj_to_encoder(mo) : NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment