drm: Update connector documentation

- Shuffle docs from drm-kms.rst into the structure docs where it makes
  sense.
- Put the remaining bits into a new overview section.

One thing I've changed is around probing: Old docs says that you
_must_ use the probe helpers, which isn't correct. Helpers are always
optional.

v2: Review from Sean.

Cc: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471034937-651-17-git-send-email-daniel.vetter@ffwll.ch
This commit is contained in:
Daniel Vetter 2016-08-12 22:48:53 +02:00
parent e15c8f4b6e
commit ae2a6da876
3 changed files with 94 additions and 166 deletions

View File

@ -110,8 +110,14 @@ Display Modes Function Reference
.. kernel-doc:: drivers/gpu/drm/drm_modes.c
:export:
Connector Display Sink Abstraction
==================================
Connector Abstraction
=====================
.. kernel-doc:: drivers/gpu/drm/drm_connector.c
:doc: overview
Connector Functions Reference
-----------------------------
.. kernel-doc:: include/drm/drm_connector.h
:internal:
@ -232,166 +238,6 @@ 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.
Connectors (:c:type:`struct drm_connector <drm_connector>`)
-----------------------------------------------------------
A connector is the final destination for pixel data on a device, and
usually connects directly to an external display device like a monitor
or laptop panel. A connector can only be attached to one encoder at a
time. The connector is also the structure where information about the
attached display is kept, so it contains fields for display data, EDID
data, DPMS & connection status, and information about modes supported on
the attached displays.
Connector Initialization
~~~~~~~~~~~~~~~~~~~~~~~~
Finally a KMS driver must create, initialize, register and attach at
least one :c:type:`struct drm_connector <drm_connector>`
instance. The instance is created as other KMS objects and initialized
by setting the following fields.
interlace_allowed
Whether the connector can handle interlaced modes.
doublescan_allowed
Whether the connector can handle doublescan.
display_info
Display information is filled from EDID information when a display
is detected. For non hot-pluggable displays such as flat panels in
embedded systems, the driver should initialize the
display_info.width_mm and display_info.height_mm fields with the
physical size of the display.
polled
Connector polling mode, a combination of
DRM_CONNECTOR_POLL_HPD
The connector generates hotplug events and doesn't need to be
periodically polled. The CONNECT and DISCONNECT flags must not
be set together with the HPD flag.
DRM_CONNECTOR_POLL_CONNECT
Periodically poll the connector for connection.
DRM_CONNECTOR_POLL_DISCONNECT
Periodically poll the connector for disconnection.
Set to 0 for connectors that don't support connection status
discovery.
The connector is then registered with a call to
:c:func:`drm_connector_init()` with a pointer to the connector
functions and a connector type, and exposed through sysfs with a call to
:c:func:`drm_connector_register()`.
Supported connector types are
- DRM_MODE_CONNECTOR_VGA
- DRM_MODE_CONNECTOR_DVII
- DRM_MODE_CONNECTOR_DVID
- DRM_MODE_CONNECTOR_DVIA
- DRM_MODE_CONNECTOR_Composite
- DRM_MODE_CONNECTOR_SVIDEO
- DRM_MODE_CONNECTOR_LVDS
- DRM_MODE_CONNECTOR_Component
- DRM_MODE_CONNECTOR_9PinDIN
- DRM_MODE_CONNECTOR_DisplayPort
- DRM_MODE_CONNECTOR_HDMIA
- DRM_MODE_CONNECTOR_HDMIB
- DRM_MODE_CONNECTOR_TV
- DRM_MODE_CONNECTOR_eDP
- DRM_MODE_CONNECTOR_VIRTUAL
Connectors must be attached to an encoder to be used. For devices that
map connectors to encoders 1:1, the connector should be attached at
initialization time with a call to
:c:func:`drm_mode_connector_attach_encoder()`. The driver must
also set the :c:type:`struct drm_connector <drm_connector>`
encoder field to point to the attached encoder.
Finally, drivers must initialize the connectors state change detection
with a call to :c:func:`drm_kms_helper_poll_init()`. If at least
one connector is pollable but can't generate hotplug interrupts
(indicated by the DRM_CONNECTOR_POLL_CONNECT and
DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will
automatically be queued to periodically poll for changes. Connectors
that can generate hotplug interrupts must be marked with the
DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must
call :c:func:`drm_helper_hpd_irq_event()`. The function will
queue a delayed work to check the state of all connectors, but no
periodic polling will be done.
Connector Operations
~~~~~~~~~~~~~~~~~~~~
**Note**
Unless otherwise state, all operations are mandatory.
DPMS
''''
void (\*dpms)(struct drm_connector \*connector, int mode);
The DPMS operation sets the power state of a connector. The mode
argument is one of
- DRM_MODE_DPMS_ON
- DRM_MODE_DPMS_STANDBY
- DRM_MODE_DPMS_SUSPEND
- DRM_MODE_DPMS_OFF
In all but DPMS_ON mode the encoder to which the connector is attached
should put the display in low-power mode by driving its signals
appropriately. If more than one connector is attached to the encoder
care should be taken not to change the power state of other displays as
a side effect. Low-power mode should be propagated to the encoders and
CRTCs when all related connectors are put in low-power mode.
Modes
'''''
int (\*fill_modes)(struct drm_connector \*connector, uint32_t
max_width, uint32_t max_height);
Fill the mode list with all supported modes for the connector. If the
``max_width`` and ``max_height`` arguments are non-zero, the
implementation must ignore all modes wider than ``max_width`` or higher
than ``max_height``.
The connector must also fill in this operation its display_info
width_mm and height_mm fields with the connected display physical size
in millimeters. The fields should be set to 0 if the value isn't known
or is not applicable (for instance for projector devices).
Connection Status
'''''''''''''''''
The connection status is updated through polling or hotplug events when
supported (see ?). The status value is reported to userspace through
ioctls and must not be used inside the driver, as it only gets
initialized by a call to :c:func:`drm_mode_getconnector()` from
userspace.
enum drm_connector_status (\*detect)(struct drm_connector
\*connector, bool force);
Check to see if anything is attached to the connector. The ``force``
parameter is set to false whilst polling or to true when checking the
connector due to user request. ``force`` can be used by the driver to
avoid expensive, destructive operations during automated probing.
Return connector_status_connected if something is connected to the
connector, connector_status_disconnected if nothing is connected and
connector_status_unknown if the connection state isn't known.
Drivers should only return connector_status_connected if the
connection status has really been probed as connected. Connectors that
can't detect the connection status, or failed connection status probes,
should return connector_status_unknown.
Cleanup
-------

View File

@ -27,6 +27,37 @@
#include "drm_crtc_internal.h"
#include "drm_internal.h"
/**
* DOC: overview
*
* In DRM connectors are the general abstraction for display sinks, and include
* als fixed panels or anything else that can display pixels in some form. As
* opposed to all other KMS objects representing hardware (like CRTC, encoder or
* plane abstractions) connectors can be hotplugged and unplugged at runtime.
* Hence they are reference-counted using drm_connector_reference() and
* drm_connector_unreference().
*
* KMS driver must create, initialize, register and attach at a struct
* &drm_connector for each such sink. The instance is created as other KMS
* objects and initialized by setting the following fields.
*
* The connector is then registered with a call to drm_connector_init() with a
* pointer to the connector functions and a connector type, and exposed through
* sysfs with a call to drm_connector_register().
*
* Connectors must be attached to an encoder to be used. For devices that map
* connectors to encoders 1:1, the connector should be attached at
* initialization time with a call to drm_mode_connector_attach_encoder(). The
* driver must also set the struct &drm_connector encoder field to point to the
* attached encoder.
*
* For connectors which are not fixed (like built-in panels) the driver needs to
* support hotplug notifications. The simplest way to do that is by using the
* probe helpers, see drm_kms_helper_poll_init() for connectors which don't have
* hardware support for hotplug interrupts. Connectors with hardware hotplug
* support can instead use e.g. drm_helper_hpd_irq_event().
*/
struct drm_conn_prop_enum_list {
int type;
const char *name;
@ -77,7 +108,7 @@ void drm_connector_ida_destroy(void)
* drm_connector_get_cmdline_mode - reads the user's cmdline mode
* @connector: connector to quwery
*
* The kernel supports per-connector configration of its consoles through
* The kernel supports per-connector configuration of its consoles through
* use of the video= parameter. This function parses that option and
* extracts the user's specified mode (or enable/disable status) for a
* particular connector. This is typically only used during the early fbdev

View File

@ -42,9 +42,36 @@ enum drm_connector_force {
DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
};
/**
* enum drm_connector_status - status for a &drm_connector
*
* This enum is used to track the connector status. There are no separate
* #defines for the uapi!
*/
enum drm_connector_status {
/**
* @connector_status_connected: The connector is definitely connected to
* a sink device, and can be enabled.
*/
connector_status_connected = 1,
/**
* @connector_status_disconnected: The connector isn't connected to a
* sink device which can be autodetect. For digital outputs like DP or
* HDMI (which can be realiable probed) this means there's really
* nothing there. It is driver-dependent whether a connector with this
* status can be lit up or not.
*/
connector_status_disconnected = 2,
/**
* @connector_status_unknown: The connector's status could not be
* reliably detected. This happens when probing would either cause
* flicker (like load-detection when the connector is in use), or when a
* hardware resource isn't available (like when load-detection needs a
* free CRTC). It should be possible to light up the connector with one
* of the listed fallback modes. For default configuration userspace
* should only try to light up connectors with unknown status when
* there's not connector with @connector_status_connected.
*/
connector_status_unknown = 3,
};
@ -416,11 +443,9 @@ struct drm_cmdline_mode {
* @modes: modes available on this connector (from fill_modes() + user)
* @status: one of the drm_connector_status enums (connected, not, or unknown)
* @probed_modes: list of modes derived directly from the display
* @display_info: information about attached display (e.g. from EDID)
* @funcs: connector control functions
* @edid_blob_ptr: DRM property containing EDID if present
* @properties: property tracking for this connector
* @polled: a DRM_CONNECTOR_POLL_<foo> value for core driven polling
* @dpms: current dpms state
* @helper_private: mid-layer private data
* @cmdline_mode: mode line parsed from the kernel cmdline for this connector
@ -485,6 +510,13 @@ struct drm_connector {
/* these are modes added by probing with DDC or the BIOS */
struct list_head probed_modes;
/**
* @display_info: Display information is filled from EDID information
* when a display is detected. For non hot-pluggable displays such as
* flat panels in embedded systems, the driver should initialize the
* display_info.width_mm and display_info.height_mm fields with the
* physical size of the display.
*/
struct drm_display_info display_info;
const struct drm_connector_funcs *funcs;
@ -519,7 +551,26 @@ struct drm_connector {
/* DACs should rarely do this without a lot of testing */
#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
uint8_t polled; /* DRM_CONNECTOR_POLL_* */
/**
* @polled:
*
* Connector polling mode, a combination of
*
* DRM_CONNECTOR_POLL_HPD
* The connector generates hotplug events and doesn't need to be
* periodically polled. The CONNECT and DISCONNECT flags must not
* be set together with the HPD flag.
*
* DRM_CONNECTOR_POLL_CONNECT
* Periodically poll the connector for connection.
*
* DRM_CONNECTOR_POLL_DISCONNECT
* Periodically poll the connector for disconnection.
*
* Set to 0 for connectors that don't support connection status
* discovery.
*/
uint8_t polled;
/* requested DPMS state */
int dpms;