Merge tag 'topic/drm-misc-2015-12-14' of git://anongit.freedesktop.org/drm-intel into drm-next
Last (very likely at least) drm-misc pull for 4.5. 3 big things: - piles of docs for kms vtables. - drm.debug dmesg output prettification from Ville (i915 parts are for 4.6 I think) - connector mode probing/validating/merging cleanup from Ville. [airlied : fix drm_encoder_init conflict.] * tag 'topic/drm-misc-2015-12-14' of git://anongit.freedesktop.org/drm-intel: (43 commits) drm: modes: Revert cc344980c767 "replace simple_strtoul by kstrtouint" drm: Expand the drm_helper_probe_single_connector_modes() docs drm: Allow override_edid to override the firmware EDID drm/sti: Drop bogus drm_mode_sort() call drm: Drop drm_helper_probe_single_connector_modes_nomerge() drm: Only merge mode type bits between new probed modes drm: Flatten drm_mode_connector_list_update() a bit drm: Rename MODE_UNVERIFIED to MODE_STALE drm: Don't overwrite UNVERFIED mode status to OK drm: Add plane->name and use it in debug prints drm: Add crtc->name and use it in debug messages drm: Use driver specified encoder name drm: Pass 'name' to drm_encoder_init() drm: Pass 'name' to drm_universal_plane_init() drm: Pass 'name' to drm_crtc_init_with_planes() drm: Documentation style guide drm: Document drm_encoder/crtc_helper_funcs drm: Move drm_display_mode an related docs into kerneldoc drm/atomic-helper: Mention the new system/resume helpers the docs drm: Document drm_connector_helper_funcs ...
This commit is contained in:
@ -124,6 +124,43 @@
|
||||
<para>
|
||||
[Insert diagram of typical DRM stack here]
|
||||
</para>
|
||||
<sect1>
|
||||
<title>Style Guidelines</title>
|
||||
<para>
|
||||
For consistency this documentation uses American English. Abbreviations
|
||||
are written as all-uppercase, for example: DRM, KMS, IOCTL, CRTC, and so
|
||||
on. To aid in reading, documentations make full use of the markup
|
||||
characters kerneldoc provides: @parameter for function parameters, @member
|
||||
for structure members, &structure to reference structures and
|
||||
function() for functions. These all get automatically hyperlinked if
|
||||
kerneldoc for the referenced objects exists. When referencing entries in
|
||||
function vtables please use ->vfunc(). Note that kerneldoc does
|
||||
not support referencing struct members directly, so please add a reference
|
||||
to the vtable struct somewhere in the same paragraph or at least section.
|
||||
</para>
|
||||
<para>
|
||||
Except in special situations (to separate locked from unlocked variants)
|
||||
locking requirements for functions aren't documented in the kerneldoc.
|
||||
Instead locking should be check at runtime using e.g.
|
||||
<code>WARN_ON(!mutex_is_locked(...));</code>. Since it's much easier to
|
||||
ignore documentation than runtime noise this provides more value. And on
|
||||
top of that runtime checks do need to be updated when the locking rules
|
||||
change, increasing the chances that they're correct. Within the
|
||||
documentation the locking rules should be explained in the relevant
|
||||
structures: Either in the comment for the lock explaining what it
|
||||
protects, or data fields need a note about which lock protects them, or
|
||||
both.
|
||||
</para>
|
||||
<para>
|
||||
Functions which have a non-<code>void</code> return value should have a
|
||||
section called "Returns" explaining the expected return values in
|
||||
different cases and their meanings. Currently there's no consensus whether
|
||||
that section name should be all upper-case or not, and whether it should
|
||||
end in a colon or not. Go with the file-local style. Other common section
|
||||
names are "Notes" with information for dangerous or tricky corner cases,
|
||||
and "FIXME" where the interface could be cleaned up.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<!-- Internals -->
|
||||
@ -946,6 +983,7 @@ int max_width, max_height;</synopsis>
|
||||
<sect2>
|
||||
<title>Atomic Mode Setting Function Reference</title>
|
||||
!Edrivers/gpu/drm/drm_atomic.c
|
||||
!Idrivers/gpu/drm/drm_atomic.c
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Frame Buffer Creation</title>
|
||||
@ -1173,137 +1211,6 @@ int max_width, max_height;</synopsis>
|
||||
pointer to CRTC functions.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3 id="drm-kms-crtcops">
|
||||
<title>CRTC Operations</title>
|
||||
<sect4>
|
||||
<title>Set Configuration</title>
|
||||
<synopsis>int (*set_config)(struct drm_mode_set *set);</synopsis>
|
||||
<para>
|
||||
Apply a new CRTC configuration to the device. The configuration
|
||||
specifies a CRTC, a frame buffer to scan out from, a (x,y) position in
|
||||
the frame buffer, a display mode and an array of connectors to drive
|
||||
with the CRTC if possible.
|
||||
</para>
|
||||
<para>
|
||||
If the frame buffer specified in the configuration is NULL, the driver
|
||||
must detach all encoders connected to the CRTC and all connectors
|
||||
attached to those encoders and disable them.
|
||||
</para>
|
||||
<para>
|
||||
This operation is called with the mode config lock held.
|
||||
</para>
|
||||
<note><para>
|
||||
Note that the drm core has no notion of restoring the mode setting
|
||||
state after resume, since all resume handling is in the full
|
||||
responsibility of the driver. The common mode setting helper library
|
||||
though provides a helper which can be used for this:
|
||||
<function>drm_helper_resume_force_mode</function>.
|
||||
</para></note>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Page Flipping</title>
|
||||
<synopsis>int (*page_flip)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event);</synopsis>
|
||||
<para>
|
||||
Schedule a page flip to the given frame buffer for the CRTC. This
|
||||
operation is called with the mode config mutex held.
|
||||
</para>
|
||||
<para>
|
||||
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. 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 <methodname>page_flip</methodname> operation with a
|
||||
pointer to the new frame buffer.
|
||||
</para>
|
||||
<para>
|
||||
The <methodname>page_flip</methodname> operation schedules a page flip.
|
||||
Once any pending rendering targeting the new frame buffer has
|
||||
completed, the CRTC will be reprogrammed to display that frame buffer
|
||||
after the next vertical refresh. The operation must return immediately
|
||||
without waiting for rendering or page flip to complete and must block
|
||||
any new rendering to the frame buffer until the page flip completes.
|
||||
</para>
|
||||
<para>
|
||||
If a page flip can be successfully scheduled the driver must set the
|
||||
<code>drm_crtc->fb</code> field to the new framebuffer pointed to
|
||||
by <code>fb</code>. This is important so that the reference counting
|
||||
on framebuffers stays balanced.
|
||||
</para>
|
||||
<para>
|
||||
If a page flip is already pending, the
|
||||
<methodname>page_flip</methodname> operation must return
|
||||
-<errorname>EBUSY</errorname>.
|
||||
</para>
|
||||
<para>
|
||||
To synchronize page flip to vertical blanking the driver will likely
|
||||
need to enable vertical blanking interrupts. It should call
|
||||
<function>drm_vblank_get</function> for that purpose, and call
|
||||
<function>drm_vblank_put</function> after the page flip completes.
|
||||
</para>
|
||||
<para>
|
||||
If the application has requested to be notified when page flip completes
|
||||
the <methodname>page_flip</methodname> operation will be called with a
|
||||
non-NULL <parameter>event</parameter> argument pointing to a
|
||||
<structname>drm_pending_vblank_event</structname> instance. Upon page
|
||||
flip completion the driver must call <methodname>drm_send_vblank_event</methodname>
|
||||
to fill in the event and send to wake up any waiting processes.
|
||||
This can be performed with
|
||||
<programlisting><![CDATA[
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
...
|
||||
drm_send_vblank_event(dev, pipe, event);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
]]></programlisting>
|
||||
</para>
|
||||
<note><para>
|
||||
FIXME: Could drivers that don't need to wait for rendering to complete
|
||||
just add the event to <literal>dev->vblank_event_list</literal> and
|
||||
let the DRM core handle everything, as for "normal" vertical blanking
|
||||
events?
|
||||
</para></note>
|
||||
<para>
|
||||
While waiting for the page flip to complete, the
|
||||
<literal>event->base.link</literal> list head can be used freely by
|
||||
the driver to store the pending event in a driver-specific list.
|
||||
</para>
|
||||
<para>
|
||||
If the file handle is closed before the event is signaled, drivers must
|
||||
take care to destroy the event in their
|
||||
<methodname>preclose</methodname> operation (and, if needed, call
|
||||
<function>drm_vblank_put</function>).
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Miscellaneous</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>void (*set_property)(struct drm_crtc *crtc,
|
||||
struct drm_property *property, uint64_t value);</synopsis>
|
||||
<para>
|
||||
Set the value of the given CRTC property to
|
||||
<parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
|
||||
for more information about properties.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size);</synopsis>
|
||||
<para>
|
||||
Apply a gamma table to the device. The operation is optional.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void (*destroy)(struct drm_crtc *crtc);</synopsis>
|
||||
<para>
|
||||
Destroy the CRTC when not needed anymore. See
|
||||
<xref linkend="drm-kms-init"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect4>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Planes (struct <structname>drm_plane</structname>)</title>
|
||||
@ -1320,7 +1227,7 @@ int max_width, max_height;</synopsis>
|
||||
<listitem>
|
||||
DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. Primary
|
||||
planes are the planes operated upon by CRTC modesetting and flipping
|
||||
operations described in <xref linkend="drm-kms-crtcops"/>.
|
||||
operations described in the page_flip hook in <structname>drm_crtc_funcs</structname>.
|
||||
</listitem>
|
||||
<listitem>
|
||||
DRM_PLANE_TYPE_CURSOR represents a "cursor" plane for a CRTC. Cursor
|
||||
@ -1357,52 +1264,6 @@ int max_width, max_height;</synopsis>
|
||||
primary plane with standard capabilities.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Plane Operations</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>int (*update_plane)(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
uint32_t src_x, uint32_t src_y,
|
||||
uint32_t src_w, uint32_t src_h);</synopsis>
|
||||
<para>
|
||||
Enable and configure the plane to use the given CRTC and frame buffer.
|
||||
</para>
|
||||
<para>
|
||||
The source rectangle in frame buffer memory coordinates is given by
|
||||
the <parameter>src_x</parameter>, <parameter>src_y</parameter>,
|
||||
<parameter>src_w</parameter> and <parameter>src_h</parameter>
|
||||
parameters (as 16.16 fixed point values). Devices that don't support
|
||||
subpixel plane coordinates can ignore the fractional part.
|
||||
</para>
|
||||
<para>
|
||||
The destination rectangle in CRTC coordinates is given by the
|
||||
<parameter>crtc_x</parameter>, <parameter>crtc_y</parameter>,
|
||||
<parameter>crtc_w</parameter> and <parameter>crtc_h</parameter>
|
||||
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.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>int (*disable_plane)(struct drm_plane *plane);</synopsis>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void (*destroy)(struct drm_plane *plane);</synopsis>
|
||||
<para>
|
||||
Destroy the plane when not needed anymore. See
|
||||
<xref linkend="drm-kms-init"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Encoders (struct <structname>drm_encoder</structname>)</title>
|
||||
@ -1459,27 +1320,6 @@ int max_width, max_height;</synopsis>
|
||||
encoders they want to use to a CRTC.
|
||||
</para>
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Encoder Operations</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>void (*destroy)(struct drm_encoder *encoder);</synopsis>
|
||||
<para>
|
||||
Called to destroy the encoder when not needed anymore. See
|
||||
<xref linkend="drm-kms-init"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void (*set_property)(struct drm_plane *plane,
|
||||
struct drm_property *property, uint64_t value);</synopsis>
|
||||
<para>
|
||||
Set the value of the given plane property to
|
||||
<parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
|
||||
for more information about properties.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Connectors (struct <structname>drm_connector</structname>)</title>
|
||||
@ -1683,27 +1523,6 @@ int max_width, max_height;</synopsis>
|
||||
connector_status_unknown.
|
||||
</para>
|
||||
</sect4>
|
||||
<sect4>
|
||||
<title>Miscellaneous</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>void (*set_property)(struct drm_connector *connector,
|
||||
struct drm_property *property, uint64_t value);</synopsis>
|
||||
<para>
|
||||
Set the value of the given connector property to
|
||||
<parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
|
||||
for more information about properties.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void (*destroy)(struct drm_connector *connector);</synopsis>
|
||||
<para>
|
||||
Destroy the connector when not needed anymore. See
|
||||
<xref linkend="drm-kms-init"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect4>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
@ -1830,83 +1649,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||
entities.
|
||||
</para>
|
||||
<sect2>
|
||||
<title>Helper Functions</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>int drm_crtc_helper_set_config(struct drm_mode_set *set);</synopsis>
|
||||
<para>
|
||||
The <function>drm_crtc_helper_set_config</function> helper function
|
||||
is a CRTC <methodname>set_config</methodname> implementation. It
|
||||
first tries to locate the best encoder for each connector by calling
|
||||
the connector <methodname>best_encoder</methodname> helper
|
||||
operation.
|
||||
</para>
|
||||
<para>
|
||||
After locating the appropriate encoders, the helper function will
|
||||
call the <methodname>mode_fixup</methodname> encoder and CRTC helper
|
||||
operations to adjust the requested mode, or reject it completely in
|
||||
which case an error will be returned to the application. If the new
|
||||
configuration after mode adjustment is identical to the current
|
||||
configuration the helper function will return without performing any
|
||||
other operation.
|
||||
</para>
|
||||
<para>
|
||||
If the adjusted mode is identical to the current mode but changes to
|
||||
the frame buffer need to be applied, the
|
||||
<function>drm_crtc_helper_set_config</function> function will call
|
||||
the CRTC <methodname>mode_set_base</methodname> helper operation. If
|
||||
the adjusted mode differs from the current mode, or if the
|
||||
<methodname>mode_set_base</methodname> helper operation is not
|
||||
provided, the helper function performs a full mode set sequence by
|
||||
calling the <methodname>prepare</methodname>,
|
||||
<methodname>mode_set</methodname> and
|
||||
<methodname>commit</methodname> CRTC and encoder helper operations,
|
||||
in that order.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>void drm_helper_connector_dpms(struct drm_connector *connector, int mode);</synopsis>
|
||||
<para>
|
||||
The <function>drm_helper_connector_dpms</function> helper function
|
||||
is a connector <methodname>dpms</methodname> implementation that
|
||||
tracks power state of connectors. To use the function, drivers must
|
||||
provide <methodname>dpms</methodname> helper operations for CRTCs
|
||||
and encoders to apply the DPMS state to the device.
|
||||
</para>
|
||||
<para>
|
||||
The mid-layer doesn't track the power state of CRTCs and encoders.
|
||||
The <methodname>dpms</methodname> helper operations can thus be
|
||||
called with a mode identical to the currently active mode.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY);</synopsis>
|
||||
<para>
|
||||
The <function>drm_helper_probe_single_connector_modes</function> helper
|
||||
function is a connector <methodname>fill_modes</methodname>
|
||||
implementation that updates the connection status for the connector
|
||||
and then retrieves a list of modes by calling the connector
|
||||
<methodname>get_modes</methodname> helper operation.
|
||||
</para>
|
||||
<para>
|
||||
If the helper operation returns no mode, and if the connector status
|
||||
is connector_status_connected, standard VESA DMT modes up to
|
||||
1024x768 are automatically added to the modes list by a call to
|
||||
<function>drm_add_modes_noedid</function>.
|
||||
</para>
|
||||
<para>
|
||||
The function then filters out modes larger than
|
||||
<parameter>max_width</parameter> and <parameter>max_height</parameter>
|
||||
if specified. It finally calls the optional connector
|
||||
<methodname>mode_valid</methodname> helper operation for each mode in
|
||||
the probed list to check whether the mode is valid for the connector.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>CRTC Helper Operations</title>
|
||||
<title>Legacy CRTC Helper Operations</title>
|
||||
<itemizedlist>
|
||||
<listitem id="drm-helper-crtc-mode-fixup">
|
||||
<synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
|
||||
@ -2051,198 +1794,6 @@ void intel_crt_init(struct drm_device *dev)
|
||||
connector_status_connected. There is no need to call
|
||||
<function>drm_add_edid_modes</function> manually in that case.
|
||||
</para>
|
||||
<para>
|
||||
When adding modes manually the driver creates each mode with a call to
|
||||
<function>drm_mode_create</function> and must fill the following fields.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<synopsis>__u32 type;</synopsis>
|
||||
<para>
|
||||
Mode type bitmask, a combination of
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_BUILTIN</term>
|
||||
<listitem><para>not used?</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_CLOCK_C</term>
|
||||
<listitem><para>not used?</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_CRTC_C</term>
|
||||
<listitem><para>not used?</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
DRM_MODE_TYPE_PREFERRED - The preferred mode for the connector
|
||||
</term>
|
||||
<listitem>
|
||||
<para>not used?</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_DEFAULT</term>
|
||||
<listitem><para>not used?</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_USERDEF</term>
|
||||
<listitem><para>not used?</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_TYPE_DRIVER</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The mode has been created by the driver (as opposed to
|
||||
to user-created modes).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
Drivers must set the DRM_MODE_TYPE_DRIVER bit for all modes they
|
||||
create, and set the DRM_MODE_TYPE_PREFERRED bit for the preferred
|
||||
mode.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>__u32 clock;</synopsis>
|
||||
<para>Pixel clock frequency in kHz unit</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>__u16 hdisplay, hsync_start, hsync_end, htotal;
|
||||
__u16 vdisplay, vsync_start, vsync_end, vtotal;</synopsis>
|
||||
<para>Horizontal and vertical timing information</para>
|
||||
<screen><![CDATA[
|
||||
Active Front Sync Back
|
||||
Region Porch Porch
|
||||
<-----------------------><----------------><-------------><-------------->
|
||||
|
||||
//////////////////////|
|
||||
////////////////////// |
|
||||
////////////////////// |.................. ................
|
||||
_______________
|
||||
|
||||
<----- [hv]display ----->
|
||||
<------------- [hv]sync_start ------------>
|
||||
<--------------------- [hv]sync_end --------------------->
|
||||
<-------------------------------- [hv]total ----------------------------->
|
||||
]]></screen>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>__u16 hskew;
|
||||
__u16 vscan;</synopsis>
|
||||
<para>Unknown</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>__u32 flags;</synopsis>
|
||||
<para>
|
||||
Mode flags, a combination of
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_PHSYNC</term>
|
||||
<listitem><para>
|
||||
Horizontal sync is active high
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_NHSYNC</term>
|
||||
<listitem><para>
|
||||
Horizontal sync is active low
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_PVSYNC</term>
|
||||
<listitem><para>
|
||||
Vertical sync is active high
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_NVSYNC</term>
|
||||
<listitem><para>
|
||||
Vertical sync is active low
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_INTERLACE</term>
|
||||
<listitem><para>
|
||||
Mode is interlaced
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_DBLSCAN</term>
|
||||
<listitem><para>
|
||||
Mode uses doublescan
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_CSYNC</term>
|
||||
<listitem><para>
|
||||
Mode uses composite sync
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_PCSYNC</term>
|
||||
<listitem><para>
|
||||
Composite sync is active high
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_NCSYNC</term>
|
||||
<listitem><para>
|
||||
Composite sync is active low
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_HSKEW</term>
|
||||
<listitem><para>
|
||||
hskew provided (not used?)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_BCAST</term>
|
||||
<listitem><para>
|
||||
not used?
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_PIXMUX</term>
|
||||
<listitem><para>
|
||||
not used?
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_DBLCLK</term>
|
||||
<listitem><para>
|
||||
not used?
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>DRM_MODE_FLAG_CLKDIV2</term>
|
||||
<listitem><para>
|
||||
?
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
<para>
|
||||
Note that modes marked with the INTERLACE or DBLSCAN flags will be
|
||||
filtered out by
|
||||
<function>drm_helper_probe_single_connector_modes</function> if
|
||||
the connector's <structfield>interlace_allowed</structfield> or
|
||||
<structfield>doublescan_allowed</structfield> field is set to 0.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<synopsis>char name[DRM_DISPLAY_MODE_LEN];</synopsis>
|
||||
<para>
|
||||
Mode name. The driver must call
|
||||
<function>drm_mode_set_name</function> to fill the mode name from
|
||||
<structfield>hdisplay</structfield>,
|
||||
<structfield>vdisplay</structfield> and interlace flag after
|
||||
filling the corresponding fields.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
The <structfield>vrefresh</structfield> value is computed by
|
||||
<function>drm_helper_probe_single_connector_modes</function>.
|
||||
@ -2303,8 +1854,12 @@ void intel_crt_init(struct drm_device *dev)
|
||||
!Edrivers/gpu/drm/drm_atomic_helper.c
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Modeset Helper Functions Reference</title>
|
||||
!Iinclude/drm/drm_crtc_helper.h
|
||||
<title>Modeset Helper Reference for Common Vtables</title>
|
||||
!Iinclude/drm/drm_modeset_helper_vtables.h
|
||||
!Pinclude/drm/drm_modeset_helper_vtables.h overview
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Legacy CRTC/Modeset Helper Functions Reference</title>
|
||||
!Edrivers/gpu/drm/drm_crtc_helper.c
|
||||
!Pdrivers/gpu/drm/drm_crtc_helper.c overview
|
||||
</sect2>
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_fixed.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
@ -3729,7 +3729,7 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev,
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v10_0_dac_helper_funcs);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||
@ -3740,15 +3740,15 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev,
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
amdgpu_encoder->rmx_type = RMX_FULL;
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder);
|
||||
} else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
} else {
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
}
|
||||
drm_encoder_helper_add(encoder, &dce_v10_0_dig_helper_funcs);
|
||||
@ -3766,13 +3766,13 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev,
|
||||
amdgpu_encoder->is_ext_encoder = true;
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
else
|
||||
drm_encoder_init(dev, encoder, &dce_v10_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v10_0_ext_helper_funcs);
|
||||
break;
|
||||
}
|
||||
|
@ -3722,7 +3722,7 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v11_0_dac_helper_funcs);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||
@ -3733,15 +3733,15 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
amdgpu_encoder->rmx_type = RMX_FULL;
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder);
|
||||
} else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
} else {
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
}
|
||||
drm_encoder_helper_add(encoder, &dce_v11_0_dig_helper_funcs);
|
||||
@ -3759,13 +3759,13 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
|
||||
amdgpu_encoder->is_ext_encoder = true;
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
else
|
||||
drm_encoder_init(dev, encoder, &dce_v11_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v11_0_ext_helper_funcs);
|
||||
break;
|
||||
}
|
||||
|
@ -3659,7 +3659,7 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v8_0_dac_helper_funcs);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||
@ -3670,15 +3670,15 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
amdgpu_encoder->rmx_type = RMX_FULL;
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_lcd_info(amdgpu_encoder);
|
||||
} else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
} else {
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
amdgpu_encoder->enc_priv = amdgpu_atombios_encoder_get_dig_info(amdgpu_encoder);
|
||||
}
|
||||
drm_encoder_helper_add(encoder, &dce_v8_0_dig_helper_funcs);
|
||||
@ -3696,13 +3696,13 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
|
||||
amdgpu_encoder->is_ext_encoder = true;
|
||||
if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
else if (amdgpu_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
else
|
||||
drm_encoder_init(dev, encoder, &dce_v8_0_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_v8_0_ext_helper_funcs);
|
||||
break;
|
||||
}
|
||||
|
@ -1216,14 +1216,14 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
|
||||
&armada_primary_plane_funcs,
|
||||
armada_primary_formats,
|
||||
ARRAY_SIZE(armada_primary_formats),
|
||||
DRM_PLANE_TYPE_PRIMARY);
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
|
||||
&armada_crtc_funcs);
|
||||
&armada_crtc_funcs, NULL);
|
||||
if (ret)
|
||||
goto err_crtc_init;
|
||||
|
||||
|
@ -460,7 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
|
||||
&armada_ovl_plane_funcs,
|
||||
armada_ovl_formats,
|
||||
ARRAY_SIZE(armada_ovl_formats),
|
||||
DRM_PLANE_TYPE_OVERLAY);
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
if (ret) {
|
||||
kfree(dplane);
|
||||
return ret;
|
||||
|
@ -751,7 +751,7 @@ static int ast_encoder_init(struct drm_device *dev)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_encoder_init(dev, &ast_encoder->base, &ast_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(&ast_encoder->base, &ast_enc_helper_funcs);
|
||||
|
||||
ast_encoder->base.possible_crtcs = 1;
|
||||
|
@ -344,7 +344,7 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev)
|
||||
ret = drm_crtc_init_with_planes(dev, &crtc->base,
|
||||
&planes->primary->base,
|
||||
planes->cursor ? &planes->cursor->base : NULL,
|
||||
&atmel_hlcdc_crtc_funcs);
|
||||
&atmel_hlcdc_crtc_funcs, NULL);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -256,7 +256,7 @@ static int atmel_hlcdc_create_panel_output(struct drm_device *dev,
|
||||
&atmel_hlcdc_panel_encoder_helper_funcs);
|
||||
ret = drm_encoder_init(dev, &panel->base.encoder,
|
||||
&atmel_hlcdc_panel_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -941,7 +941,7 @@ atmel_hlcdc_plane_create(struct drm_device *dev,
|
||||
ret = drm_universal_plane_init(dev, &plane->base, 0,
|
||||
&layer_plane_funcs,
|
||||
desc->formats->formats,
|
||||
desc->formats->nformats, type);
|
||||
desc->formats->nformats, type, NULL);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
@ -196,7 +196,7 @@ static void bochs_encoder_init(struct drm_device *dev)
|
||||
|
||||
encoder->possible_crtcs = 0x1;
|
||||
drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs);
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ static struct drm_encoder *cirrus_encoder_init(struct drm_device *dev)
|
||||
encoder->possible_crtcs = 0x1;
|
||||
|
||||
drm_encoder_init(dev, encoder, &cirrus_encoder_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &cirrus_encoder_helper_funcs);
|
||||
|
||||
return encoder;
|
||||
|
@ -288,8 +288,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
|
||||
state->crtcs[index] = crtc;
|
||||
crtc_state->state = state;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n",
|
||||
crtc->base.id, crtc_state, state);
|
||||
DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
|
||||
crtc->base.id, crtc->name, crtc_state, state);
|
||||
|
||||
return crtc_state;
|
||||
}
|
||||
@ -429,11 +429,20 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_crtc_set_property);
|
||||
|
||||
/*
|
||||
/**
|
||||
* drm_atomic_crtc_get_property - get property value from CRTC state
|
||||
* @crtc: the drm CRTC to set a property on
|
||||
* @state: the state object to get the property value from
|
||||
* @property: the property to set
|
||||
* @val: return location for the property value
|
||||
*
|
||||
* This function handles generic/core properties and calls out to
|
||||
* driver's ->atomic_get_property() for driver properties. To ensure
|
||||
* consistent behavior you must call this function rather than the
|
||||
* driver hook directly.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
static int
|
||||
drm_atomic_crtc_get_property(struct drm_crtc *crtc,
|
||||
@ -477,8 +486,8 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
|
||||
*/
|
||||
|
||||
if (state->active && !state->enable) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -487,15 +496,15 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
|
||||
* be able to trigger. */
|
||||
if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
|
||||
WARN_ON(state->enable && !state->mode_blob)) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] enabled without mode blob\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
|
||||
WARN_ON(!state->enable && state->mode_blob)) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] disabled with mode blob\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -540,8 +549,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
|
||||
state->planes[index] = plane;
|
||||
plane_state->state = state;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Added [PLANE:%d] %p state to %p\n",
|
||||
plane->base.id, plane_state, state);
|
||||
DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
|
||||
plane->base.id, plane->name, plane_state, state);
|
||||
|
||||
if (plane_state->crtc) {
|
||||
struct drm_crtc_state *crtc_state;
|
||||
@ -616,11 +625,20 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_plane_set_property);
|
||||
|
||||
/*
|
||||
/**
|
||||
* drm_atomic_plane_get_property - get property value from plane state
|
||||
* @plane: the drm plane to set a property on
|
||||
* @state: the state object to get the property value from
|
||||
* @property: the property to set
|
||||
* @val: return location for the property value
|
||||
*
|
||||
* This function handles generic/core properties and calls out to
|
||||
* driver's ->atomic_get_property() for driver properties. To ensure
|
||||
* consistent behavior you must call this function rather than the
|
||||
* driver hook directly.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
static int
|
||||
drm_atomic_plane_get_property(struct drm_plane *plane,
|
||||
@ -752,8 +770,8 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
|
||||
}
|
||||
|
||||
if (plane_switching_crtc(state->state, plane, state)) {
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d] switching CRTC directly\n",
|
||||
plane->base.id);
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
|
||||
plane->base.id, plane->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -872,11 +890,20 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_connector_set_property);
|
||||
|
||||
/*
|
||||
/**
|
||||
* drm_atomic_connector_get_property - get property value from connector state
|
||||
* @connector: the drm connector to set a property on
|
||||
* @state: the state object to get the property value from
|
||||
* @property: the property to set
|
||||
* @val: return location for the property value
|
||||
*
|
||||
* This function handles generic/core properties and calls out to
|
||||
* driver's ->atomic_get_property() for driver properties. To ensure
|
||||
* consistent behavior you must call this function rather than the
|
||||
* driver hook directly.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, error code on failure
|
||||
*/
|
||||
static int
|
||||
drm_atomic_connector_get_property(struct drm_connector *connector,
|
||||
@ -977,8 +1004,8 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
|
||||
}
|
||||
|
||||
if (crtc)
|
||||
DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n",
|
||||
plane_state, crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d:%s]\n",
|
||||
plane_state, crtc->base.id, crtc->name);
|
||||
else
|
||||
DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n",
|
||||
plane_state);
|
||||
@ -1045,8 +1072,8 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
|
||||
conn_state->crtc = crtc;
|
||||
|
||||
if (crtc)
|
||||
DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n",
|
||||
conn_state, crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d:%s]\n",
|
||||
conn_state, crtc->base.id, crtc->name);
|
||||
else
|
||||
DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n",
|
||||
conn_state);
|
||||
@ -1085,8 +1112,8 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n",
|
||||
crtc->base.id, state);
|
||||
DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
|
||||
crtc->base.id, crtc->name, state);
|
||||
|
||||
/*
|
||||
* Changed connectors are already in @state, so only need to look at the
|
||||
@ -1166,8 +1193,9 @@ drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
|
||||
num_connected_connectors++;
|
||||
}
|
||||
|
||||
DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n",
|
||||
state, num_connected_connectors, crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d:%s]\n",
|
||||
state, num_connected_connectors,
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
return num_connected_connectors;
|
||||
}
|
||||
@ -1220,8 +1248,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
|
||||
for_each_plane_in_state(state, plane, plane_state, i) {
|
||||
ret = drm_atomic_plane_check(plane, plane_state);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d] atomic core check failed\n",
|
||||
plane->base.id);
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
|
||||
plane->base.id, plane->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -1229,8 +1257,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
ret = drm_atomic_crtc_check(crtc, crtc_state);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -1241,8 +1269,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
|
||||
if (!state->allow_modeset) {
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,12 @@
|
||||
* drm_atomic_helper_disable_plane(), drm_atomic_helper_disable_plane() and the
|
||||
* various functions to implement set_property callbacks. New drivers must not
|
||||
* implement these functions themselves but must use the provided helpers.
|
||||
*
|
||||
* The atomic helper uses the same function table structures as all other
|
||||
* modesetting helpers. See the documentation for struct &drm_crtc_helper_funcs,
|
||||
* struct &drm_encoder_helper_funcs and struct &drm_connector_helper_funcs. It
|
||||
* also shares the struct &drm_plane_helper_funcs function table with the plane
|
||||
* helpers.
|
||||
*/
|
||||
static void
|
||||
drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
|
||||
@ -137,9 +143,9 @@ steal_encoder(struct drm_atomic_state *state,
|
||||
*/
|
||||
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
|
||||
|
||||
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d], stealing it\n",
|
||||
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
|
||||
encoder->base.id, encoder->name,
|
||||
encoder_crtc->base.id);
|
||||
encoder_crtc->base.id, encoder_crtc->name);
|
||||
|
||||
crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc);
|
||||
if (IS_ERR(crtc_state))
|
||||
@ -240,12 +246,13 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
|
||||
}
|
||||
|
||||
if (new_encoder == connector_state->best_encoder) {
|
||||
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d]\n",
|
||||
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
|
||||
connector->base.id,
|
||||
connector->name,
|
||||
new_encoder->base.id,
|
||||
new_encoder->name,
|
||||
connector_state->crtc->base.id);
|
||||
connector_state->crtc->base.id,
|
||||
connector_state->crtc->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -279,12 +286,13 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
|
||||
crtc_state = state->crtc_states[idx];
|
||||
crtc_state->connectors_changed = true;
|
||||
|
||||
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n",
|
||||
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
|
||||
connector->base.id,
|
||||
connector->name,
|
||||
new_encoder->base.id,
|
||||
new_encoder->name,
|
||||
connector_state->crtc->base.id);
|
||||
connector_state->crtc->base.id,
|
||||
connector_state->crtc->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -368,8 +376,8 @@ mode_fixup(struct drm_atomic_state *state)
|
||||
ret = funcs->mode_fixup(crtc, &crtc_state->mode,
|
||||
&crtc_state->adjusted_mode);
|
||||
if (!ret) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] fixup failed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -416,14 +424,14 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
||||
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] mode changed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
crtc_state->mode_changed = true;
|
||||
}
|
||||
|
||||
if (crtc->state->enable != crtc_state->enable) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
/*
|
||||
* For clarity this assignment is done here, but
|
||||
@ -464,18 +472,18 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
||||
* a full modeset because update_connector_routing force that.
|
||||
*/
|
||||
if (crtc->state->active != crtc_state->active) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] active changed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
crtc_state->active_changed = true;
|
||||
}
|
||||
|
||||
if (!drm_atomic_crtc_needs_modeset(crtc_state))
|
||||
continue;
|
||||
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] needs all connectors, enable: %c, active: %c\n",
|
||||
crtc->base.id,
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n",
|
||||
crtc->base.id, crtc->name,
|
||||
crtc_state->enable ? 'y' : 'n',
|
||||
crtc_state->active ? 'y' : 'n');
|
||||
crtc_state->active ? 'y' : 'n');
|
||||
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret != 0)
|
||||
@ -489,8 +497,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
||||
crtc);
|
||||
|
||||
if (crtc_state->enable != !!num_connectors) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] enabled/connectors mismatch\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -537,8 +545,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
|
||||
|
||||
ret = funcs->atomic_check(plane, plane_state);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d] atomic driver check failed\n",
|
||||
plane->base.id);
|
||||
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n",
|
||||
plane->base.id, plane->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -553,8 +561,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
|
||||
|
||||
ret = funcs->atomic_check(crtc, state->crtc_states[i]);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d] atomic driver check failed\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -667,8 +675,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
|
||||
|
||||
funcs = crtc->helper_private;
|
||||
|
||||
DRM_DEBUG_ATOMIC("disabling [CRTC:%d]\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
|
||||
/* Right function depends upon target state. */
|
||||
@ -779,8 +787,8 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
|
||||
funcs = crtc->helper_private;
|
||||
|
||||
if (crtc->state->enable && funcs->mode_set_nofb) {
|
||||
DRM_DEBUG_ATOMIC("modeset on [CRTC:%d]\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
funcs->mode_set_nofb(crtc);
|
||||
}
|
||||
@ -879,8 +887,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
|
||||
funcs = crtc->helper_private;
|
||||
|
||||
if (crtc->state->enable) {
|
||||
DRM_DEBUG_ATOMIC("enabling [CRTC:%d]\n",
|
||||
crtc->base.id);
|
||||
DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
||||
if (funcs->enable)
|
||||
funcs->enable(crtc);
|
||||
@ -2399,6 +2407,12 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
|
||||
* The simpler solution is to just reset the software state to everything off,
|
||||
* which is easiest to do by calling drm_mode_config_reset(). To facilitate this
|
||||
* the atomic helpers provide default reset implementations for all hooks.
|
||||
*
|
||||
* On the upside the precise state tracking of atomic simplifies system suspend
|
||||
* and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
|
||||
* is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
|
||||
* For other drivers the building blocks are split out, see the documentation
|
||||
* for these functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -31,14 +31,14 @@
|
||||
/**
|
||||
* DOC: overview
|
||||
*
|
||||
* drm_bridge represents a device that hangs on to an encoder. These are handy
|
||||
* when a regular drm_encoder entity isn't enough to represent the entire
|
||||
* struct &drm_bridge represents a device that hangs on to an encoder. These are
|
||||
* handy when a regular &drm_encoder entity isn't enough to represent the entire
|
||||
* encoder chain.
|
||||
*
|
||||
* A bridge is always associated to a single drm_encoder at a time, but can be
|
||||
* A bridge is always attached to a single &drm_encoder at a time, but can be
|
||||
* either connected to it directly, or through an intermediate bridge:
|
||||
*
|
||||
* encoder ---> bridge B ---> bridge A
|
||||
* encoder ---> bridge B ---> bridge A
|
||||
*
|
||||
* Here, the output of the encoder feeds to bridge B, and that furthers feeds to
|
||||
* bridge A.
|
||||
@ -46,11 +46,16 @@
|
||||
* The driver using the bridge is responsible to make the associations between
|
||||
* the encoder and bridges. Once these links are made, the bridges will
|
||||
* participate along with encoder functions to perform mode_set/enable/disable
|
||||
* through the ops provided in drm_bridge_funcs.
|
||||
* through the ops provided in &drm_bridge_funcs.
|
||||
*
|
||||
* drm_bridge, like drm_panel, aren't drm_mode_object entities like planes,
|
||||
* crtcs, encoders or connectors. They just provide additional hooks to get the
|
||||
* desired output at the end of the encoder chain.
|
||||
* CRTCs, encoders or connectors and hence are not visible to userspace. They
|
||||
* just provide additional hooks to get the desired output at the end of the
|
||||
* encoder chain.
|
||||
*
|
||||
* Bridges can also be chained up using the next pointer in struct &drm_bridge.
|
||||
*
|
||||
* Both legacy CRTC helpers and the new atomic modeset helpers support bridges.
|
||||
*/
|
||||
|
||||
static DEFINE_MUTEX(bridge_lock);
|
||||
@ -122,34 +127,12 @@ EXPORT_SYMBOL(drm_bridge_attach);
|
||||
/**
|
||||
* DOC: bridge callbacks
|
||||
*
|
||||
* The drm_bridge_funcs ops are populated by the bridge driver. The drm
|
||||
* internals(atomic and crtc helpers) use the helpers defined in drm_bridge.c
|
||||
* These helpers call a specific drm_bridge_funcs op for all the bridges
|
||||
* The &drm_bridge_funcs ops are populated by the bridge driver. The DRM
|
||||
* internals (atomic and CRTC helpers) use the helpers defined in drm_bridge.c
|
||||
* These helpers call a specific &drm_bridge_funcs op for all the bridges
|
||||
* during encoder configuration.
|
||||
*
|
||||
* When creating a bridge driver, one can implement drm_bridge_funcs op with
|
||||
* the help of these rough rules:
|
||||
*
|
||||
* pre_enable: this contains things needed to be done for the bridge before
|
||||
* its clock and timings are enabled by its source. For a bridge, its source
|
||||
* is generally the encoder or bridge just before it in the encoder chain.
|
||||
*
|
||||
* enable: this contains things needed to be done for the bridge once its
|
||||
* source is enabled. In other words, enable is called once the source is
|
||||
* ready with clock and timing needed by the bridge.
|
||||
*
|
||||
* disable: this contains things needed to be done for the bridge assuming
|
||||
* that its source is still enabled, i.e. clock and timings are still on.
|
||||
*
|
||||
* post_disable: this contains things needed to be done for the bridge once
|
||||
* its source is disabled, i.e. once clocks and timings are off.
|
||||
*
|
||||
* mode_fixup: this should fixup the given mode for the bridge. It is called
|
||||
* after the encoder's mode fixup. mode_fixup can also reject a mode completely
|
||||
* if it's unsuitable for the hardware.
|
||||
*
|
||||
* mode_set: this sets up the mode for the bridge. It assumes that its source
|
||||
* (an encoder or a bridge) has set the mode too.
|
||||
* For detailed specification of the bridge callbacks see &drm_bridge_funcs.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -159,7 +142,7 @@ EXPORT_SYMBOL(drm_bridge_attach);
|
||||
* @mode: desired mode to be set for the bridge
|
||||
* @adjusted_mode: updated mode that works for this bridge
|
||||
*
|
||||
* Calls 'mode_fixup' drm_bridge_funcs op for all the bridges in the
|
||||
* Calls ->mode_fixup() &drm_bridge_funcs op for all the bridges in the
|
||||
* encoder chain, starting from the first bridge to the last.
|
||||
*
|
||||
* Note: the bridge passed should be the one closest to the encoder
|
||||
@ -186,11 +169,11 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
|
||||
EXPORT_SYMBOL(drm_bridge_mode_fixup);
|
||||
|
||||
/**
|
||||
* drm_bridge_disable - calls 'disable' drm_bridge_funcs op for all
|
||||
* drm_bridge_disable - calls ->disable() &drm_bridge_funcs op for all
|
||||
* bridges in the encoder chain.
|
||||
* @bridge: bridge control structure
|
||||
*
|
||||
* Calls 'disable' drm_bridge_funcs op for all the bridges in the encoder
|
||||
* Calls ->disable() &drm_bridge_funcs op for all the bridges in the encoder
|
||||
* chain, starting from the last bridge to the first. These are called before
|
||||
* calling the encoder's prepare op.
|
||||
*
|
||||
@ -208,11 +191,11 @@ void drm_bridge_disable(struct drm_bridge *bridge)
|
||||
EXPORT_SYMBOL(drm_bridge_disable);
|
||||
|
||||
/**
|
||||
* drm_bridge_post_disable - calls 'post_disable' drm_bridge_funcs op for
|
||||
* drm_bridge_post_disable - calls ->post_disable() &drm_bridge_funcs op for
|
||||
* all bridges in the encoder chain.
|
||||
* @bridge: bridge control structure
|
||||
*
|
||||
* Calls 'post_disable' drm_bridge_funcs op for all the bridges in the
|
||||
* Calls ->post_disable() &drm_bridge_funcs op for all the bridges in the
|
||||
* encoder chain, starting from the first bridge to the last. These are called
|
||||
* after completing the encoder's prepare op.
|
||||
*
|
||||
@ -236,7 +219,7 @@ EXPORT_SYMBOL(drm_bridge_post_disable);
|
||||
* @mode: desired mode to be set for the bridge
|
||||
* @adjusted_mode: updated mode that works for this bridge
|
||||
*
|
||||
* Calls 'mode_set' drm_bridge_funcs op for all the bridges in the
|
||||
* Calls ->mode_set() &drm_bridge_funcs op for all the bridges in the
|
||||
* encoder chain, starting from the first bridge to the last.
|
||||
*
|
||||
* Note: the bridge passed should be the one closest to the encoder
|
||||
@ -256,11 +239,11 @@ void drm_bridge_mode_set(struct drm_bridge *bridge,
|
||||
EXPORT_SYMBOL(drm_bridge_mode_set);
|
||||
|
||||
/**
|
||||
* drm_bridge_pre_enable - calls 'pre_enable' drm_bridge_funcs op for all
|
||||
* drm_bridge_pre_enable - calls ->pre_enable() &drm_bridge_funcs op for all
|
||||
* bridges in the encoder chain.
|
||||
* @bridge: bridge control structure
|
||||
*
|
||||
* Calls 'pre_enable' drm_bridge_funcs op for all the bridges in the encoder
|
||||
* Calls ->pre_enable() &drm_bridge_funcs op for all the bridges in the encoder
|
||||
* chain, starting from the last bridge to the first. These are called
|
||||
* before calling the encoder's commit op.
|
||||
*
|
||||
@ -278,11 +261,11 @@ void drm_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
EXPORT_SYMBOL(drm_bridge_pre_enable);
|
||||
|
||||
/**
|
||||
* drm_bridge_enable - calls 'enable' drm_bridge_funcs op for all bridges
|
||||
* drm_bridge_enable - calls ->enable() &drm_bridge_funcs op for all bridges
|
||||
* in the encoder chain.
|
||||
* @bridge: bridge control structure
|
||||
*
|
||||
* Calls 'enable' drm_bridge_funcs op for all the bridges in the encoder
|
||||
* Calls ->enable() &drm_bridge_funcs op for all the bridges in the encoder
|
||||
* chain, starting from the first bridge to the last. These are called
|
||||
* after completing the encoder's commit op.
|
||||
*
|
||||
|
@ -649,6 +649,18 @@ EXPORT_SYMBOL(drm_framebuffer_remove);
|
||||
|
||||
DEFINE_WW_CLASS(crtc_ww_class);
|
||||
|
||||
static unsigned int drm_num_crtcs(struct drm_device *dev)
|
||||
{
|
||||
unsigned int num = 0;
|
||||
struct drm_crtc *tmp;
|
||||
|
||||
drm_for_each_crtc(tmp, dev) {
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_crtc_init_with_planes - Initialise a new CRTC object with
|
||||
* specified primary and cursor planes.
|
||||
@ -657,6 +669,7 @@ DEFINE_WW_CLASS(crtc_ww_class);
|
||||
* @primary: Primary plane for CRTC
|
||||
* @cursor: Cursor plane for CRTC
|
||||
* @funcs: callbacks for the new CRTC
|
||||
* @name: printf style format string for the CRTC name, or NULL for default name
|
||||
*
|
||||
* Inits a new object created as base part of a driver crtc object.
|
||||
*
|
||||
@ -666,7 +679,8 @@ DEFINE_WW_CLASS(crtc_ww_class);
|
||||
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, ...)
|
||||
{
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
int ret;
|
||||
@ -682,6 +696,21 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (name) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, name);
|
||||
crtc->name = kvasprintf(GFP_KERNEL, name, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
|
||||
drm_num_crtcs(dev));
|
||||
}
|
||||
if (!crtc->name) {
|
||||
drm_mode_object_put(dev, &crtc->base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
crtc->base.properties = &crtc->properties;
|
||||
|
||||
list_add_tail(&crtc->head, &config->crtc_list);
|
||||
@ -728,6 +757,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
|
||||
if (crtc->state && crtc->funcs->atomic_destroy_state)
|
||||
crtc->funcs->atomic_destroy_state(crtc, crtc->state);
|
||||
|
||||
kfree(crtc->name);
|
||||
|
||||
memset(crtc, 0, sizeof(*crtc));
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_cleanup);
|
||||
@ -1075,6 +1106,7 @@ EXPORT_SYMBOL(drm_connector_unplug_all);
|
||||
* @encoder: the encoder to init
|
||||
* @funcs: callbacks for this encoder
|
||||
* @encoder_type: user visible type of the encoder
|
||||
* @name: printf style format string for the encoder name, or NULL for default name
|
||||
*
|
||||
* Initialises a preallocated encoder. Encoder should be
|
||||
* subclassed as part of driver encoder objects.
|
||||
@ -1085,7 +1117,7 @@ EXPORT_SYMBOL(drm_connector_unplug_all);
|
||||
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, ...)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1098,9 +1130,17 @@ int drm_encoder_init(struct drm_device *dev,
|
||||
encoder->dev = dev;
|
||||
encoder->encoder_type = encoder_type;
|
||||
encoder->funcs = funcs;
|
||||
encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
|
||||
drm_encoder_enum_list[encoder_type].name,
|
||||
encoder->base.id);
|
||||
if (name) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, name);
|
||||
encoder->name = kvasprintf(GFP_KERNEL, name, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
encoder->name = kasprintf(GFP_KERNEL, "%s-%d",
|
||||
drm_encoder_enum_list[encoder_type].name,
|
||||
encoder->base.id);
|
||||
}
|
||||
if (!encoder->name) {
|
||||
ret = -ENOMEM;
|
||||
goto out_put;
|
||||
@ -1141,6 +1181,18 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_encoder_cleanup);
|
||||
|
||||
static unsigned int drm_num_planes(struct drm_device *dev)
|
||||
{
|
||||
unsigned int num = 0;
|
||||
struct drm_plane *tmp;
|
||||
|
||||
drm_for_each_plane(tmp, dev) {
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_universal_plane_init - Initialize a new universal plane object
|
||||
* @dev: DRM device
|
||||
@ -1150,6 +1202,7 @@ EXPORT_SYMBOL(drm_encoder_cleanup);
|
||||
* @formats: array of supported formats (%DRM_FORMAT_*)
|
||||
* @format_count: number of elements in @formats
|
||||
* @type: type of plane (overlay, primary, cursor)
|
||||
* @name: printf style format string for the plane name, or NULL for default name
|
||||
*
|
||||
* Initializes a plane object of type @type.
|
||||
*
|
||||
@ -1160,7 +1213,8 @@ 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, ...)
|
||||
{
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
int ret;
|
||||
@ -1182,6 +1236,22 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, name);
|
||||
plane->name = kvasprintf(GFP_KERNEL, name, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
plane->name = kasprintf(GFP_KERNEL, "plane-%d",
|
||||
drm_num_planes(dev));
|
||||
}
|
||||
if (!plane->name) {
|
||||
kfree(plane->format_types);
|
||||
drm_mode_object_put(dev, &plane->base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
|
||||
plane->format_count = format_count;
|
||||
plane->possible_crtcs = possible_crtcs;
|
||||
@ -1240,7 +1310,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
|
||||
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
||||
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
|
||||
formats, format_count, type);
|
||||
formats, format_count, type, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_init);
|
||||
|
||||
@ -1272,6 +1342,8 @@ void drm_plane_cleanup(struct drm_plane *plane)
|
||||
if (plane->state && plane->funcs->atomic_destroy_state)
|
||||
plane->funcs->atomic_destroy_state(plane, plane->state);
|
||||
|
||||
kfree(plane->name);
|
||||
|
||||
memset(plane, 0, sizeof(*plane));
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_cleanup);
|
||||
@ -1801,7 +1873,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
|
||||
copied = 0;
|
||||
crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
|
||||
drm_for_each_crtc(crtc, dev) {
|
||||
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s]\n",
|
||||
crtc->base.id, crtc->name);
|
||||
if (put_user(crtc->base.id, crtc_id + copied)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
@ -2646,7 +2719,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
|
||||
|
||||
if (crtc_req->mode_valid) {
|
||||
/* If we have a mode we need a framebuffer. */
|
||||
@ -4785,9 +4858,7 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
|
||||
|
||||
/* Do DPMS ourselves */
|
||||
if (property == connector->dev->mode_config.dpms_property) {
|
||||
ret = 0;
|
||||
if (connector->funcs->dpms)
|
||||
ret = (*connector->funcs->dpms)(connector, (int)value);
|
||||
ret = (*connector->funcs->dpms)(connector, (int)value);
|
||||
} else if (connector->funcs->set_property)
|
||||
ret = connector->funcs->set_property(connector, property, value);
|
||||
|
||||
|
@ -51,6 +51,11 @@
|
||||
* the same callbacks which drivers can use to e.g. restore the modeset
|
||||
* configuration on resume with drm_helper_resume_force_mode().
|
||||
*
|
||||
* Note that this helper library doesn't track the current power state of CRTCs
|
||||
* and encoders. It can call callbacks like ->dpms() even though the hardware is
|
||||
* already in the desired state. This deficiency has been fixed in the atomic
|
||||
* helpers.
|
||||
*
|
||||
* The driver callbacks are mostly compatible with the atomic modeset helpers,
|
||||
* except for the handling of the primary plane: Atomic helpers require that the
|
||||
* primary plane is implemented as a real standalone plane and not directly tied
|
||||
@ -62,6 +67,11 @@
|
||||
* converting to the plane helpers). New drivers must not use these functions
|
||||
* but need to implement the atomic interface instead, potentially using the
|
||||
* atomic helpers for that.
|
||||
*
|
||||
* These legacy modeset helpers use the same function table structures as
|
||||
* all other modesetting helpers. See the documentation for struct
|
||||
* &drm_crtc_helper_funcs, struct &drm_encoder_helper_funcs and struct
|
||||
* &drm_connector_helper_funcs.
|
||||
*/
|
||||
MODULE_AUTHOR("David Airlie, Jesse Barnes");
|
||||
MODULE_DESCRIPTION("DRM KMS helper");
|
||||
@ -206,8 +216,8 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
|
||||
* @dev: DRM device
|
||||
*
|
||||
* This function walks through the entire mode setting configuration of @dev. It
|
||||
* will remove any crtc links of unused encoders and encoder links of
|
||||
* disconnected connectors. Then it will disable all unused encoders and crtcs
|
||||
* will remove any CRTC links of unused encoders and encoder links of
|
||||
* disconnected connectors. Then it will disable all unused encoders and CRTCs
|
||||
* either by calling their disable callback if available or by calling their
|
||||
* dpms callback with DRM_MODE_DPMS_OFF.
|
||||
*/
|
||||
@ -329,7 +339,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
|
||||
DRM_DEBUG_KMS("CRTC fixup failed\n");
|
||||
goto done;
|
||||
}
|
||||
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
|
||||
|
||||
crtc->hwmode = *adjusted_mode;
|
||||
|
||||
@ -445,11 +455,36 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
|
||||
* drm_crtc_helper_set_config - set a new config from userspace
|
||||
* @set: mode set configuration
|
||||
*
|
||||
* Setup a new configuration, provided by the upper layers (either an ioctl call
|
||||
* from userspace or internally e.g. from the fbdev support code) in @set, and
|
||||
* enable it. This is the main helper functions for drivers that implement
|
||||
* kernel mode setting with the crtc helper functions and the assorted
|
||||
* ->prepare(), ->modeset() and ->commit() helper callbacks.
|
||||
* The drm_crtc_helper_set_config() helper function implements the set_config
|
||||
* callback of struct &drm_crtc_funcs for drivers using the legacy CRTC helpers.
|
||||
*
|
||||
* It first tries to locate the best encoder for each connector by calling the
|
||||
* connector ->best_encoder() (struct &drm_connector_helper_funcs) helper
|
||||
* operation.
|
||||
*
|
||||
* After locating the appropriate encoders, the helper function will call the
|
||||
* mode_fixup encoder and CRTC helper operations to adjust the requested mode,
|
||||
* or reject it completely in which case an error will be returned to the
|
||||
* application. If the new configuration after mode adjustment is identical to
|
||||
* the current configuration the helper function will return without performing
|
||||
* any other operation.
|
||||
*
|
||||
* If the adjusted mode is identical to the current mode but changes to the
|
||||
* frame buffer need to be applied, the drm_crtc_helper_set_config() function
|
||||
* will call the CRTC ->mode_set_base() (struct &drm_crtc_helper_funcs) helper
|
||||
* operation.
|
||||
*
|
||||
* If the adjusted mode differs from the current mode, or if the
|
||||
* ->mode_set_base() helper operation is not provided, the helper function
|
||||
* performs a full mode set sequence by calling the ->prepare(), ->mode_set()
|
||||
* and ->commit() CRTC and encoder helper operations, in that order.
|
||||
* Alternatively it can also use the dpms and disable helper operations. For
|
||||
* details see struct &drm_crtc_helper_funcs and struct
|
||||
* &drm_encoder_helper_funcs.
|
||||
*
|
||||
* This function is deprecated. New drivers must implement atomic modeset
|
||||
* support, for which this function is unsuitable. Instead drivers should use
|
||||
* drm_atomic_helper_set_config().
|
||||
*
|
||||
* Returns:
|
||||
* Returns 0 on success, negative errno numbers on failure.
|
||||
@ -484,11 +519,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
set->fb = NULL;
|
||||
|
||||
if (set->fb) {
|
||||
DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
|
||||
set->crtc->base.id, set->fb->base.id,
|
||||
(int)set->num_connectors, set->x, set->y);
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
|
||||
set->crtc->base.id, set->crtc->name,
|
||||
set->fb->base.id,
|
||||
(int)set->num_connectors, set->x, set->y);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
|
||||
set->crtc->base.id, set->crtc->name);
|
||||
drm_crtc_helper_disable(set->crtc);
|
||||
return 0;
|
||||
}
|
||||
@ -628,12 +665,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
connector->encoder->crtc = new_crtc;
|
||||
}
|
||||
if (new_crtc) {
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
|
||||
connector->base.id, connector->name,
|
||||
new_crtc->base.id);
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
|
||||
connector->base.id, connector->name,
|
||||
new_crtc->base.id, new_crtc->name);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
|
||||
connector->base.id, connector->name);
|
||||
connector->base.id, connector->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,8 +687,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
|
||||
set->x, set->y,
|
||||
save_set.fb)) {
|
||||
DRM_ERROR("failed to set mode on [CRTC:%d]\n",
|
||||
set->crtc->base.id);
|
||||
DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
|
||||
set->crtc->base.id, set->crtc->name);
|
||||
set->crtc->primary->fb = save_set.fb;
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -758,10 +795,18 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
|
||||
* @connector: affected connector
|
||||
* @mode: DPMS mode
|
||||
*
|
||||
* This is the main helper function provided by the crtc helper framework for
|
||||
* The drm_helper_connector_dpms() helper function implements the ->dpms()
|
||||
* callback of struct &drm_connector_funcs for drivers using the legacy CRTC helpers.
|
||||
*
|
||||
* This is the main helper function provided by the CRTC helper framework for
|
||||
* implementing the DPMS connector attribute. It computes the new desired DPMS
|
||||
* state for all encoders and crtcs in the output mesh and calls the ->dpms()
|
||||
* callback provided by the driver appropriately.
|
||||
* state for all encoders and CRTCs in the output mesh and calls the ->dpms()
|
||||
* callbacks provided by the driver in struct &drm_crtc_helper_funcs and struct
|
||||
* &drm_encoder_helper_funcs appropriately.
|
||||
*
|
||||
* This function is deprecated. New drivers must implement atomic modeset
|
||||
* support, for which this function is unsuitable. Instead drivers should use
|
||||
* drm_atomic_helper_connector_dpms().
|
||||
*
|
||||
* Returns:
|
||||
* Always returns 0.
|
||||
@ -919,9 +964,9 @@ EXPORT_SYMBOL(drm_helper_resume_force_mode);
|
||||
* @old_fb: previous framebuffer
|
||||
*
|
||||
* This function implements a callback useable as the ->mode_set callback
|
||||
* required by the crtc helpers. Besides the atomic plane helper functions for
|
||||
* required by the CRTC helpers. Besides the atomic plane helper functions for
|
||||
* the primary plane the driver must also provide the ->mode_set_nofb callback
|
||||
* to set up the crtc.
|
||||
* to set up the CRTC.
|
||||
*
|
||||
* This is a transitional helper useful for converting drivers to the atomic
|
||||
* interfaces.
|
||||
@ -985,7 +1030,7 @@ EXPORT_SYMBOL(drm_helper_crtc_mode_set);
|
||||
* @old_fb: previous framebuffer
|
||||
*
|
||||
* This function implements a callback useable as the ->mode_set_base used
|
||||
* required by the crtc helpers. The driver must provide the atomic plane helper
|
||||
* required by the CRTC helpers. The driver must provide the atomic plane helper
|
||||
* functions for the primary plane.
|
||||
*
|
||||
* This is a transitional helper useful for converting drivers to the atomic
|
||||
|
@ -708,7 +708,8 @@ void drm_mode_set_name(struct drm_display_mode *mode)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_set_name);
|
||||
|
||||
/** drm_mode_hsync - get the hsync of a mode
|
||||
/**
|
||||
* drm_mode_hsync - get the hsync of a mode
|
||||
* @mode: mode
|
||||
*
|
||||
* Returns:
|
||||
@ -1073,7 +1074,7 @@ static const char * const drm_mode_status_names[] = {
|
||||
MODE_STATUS(ONE_SIZE),
|
||||
MODE_STATUS(NO_REDUCED),
|
||||
MODE_STATUS(NO_STEREO),
|
||||
MODE_STATUS(UNVERIFIED),
|
||||
MODE_STATUS(STALE),
|
||||
MODE_STATUS(BAD),
|
||||
MODE_STATUS(ERROR),
|
||||
};
|
||||
@ -1171,7 +1172,6 @@ EXPORT_SYMBOL(drm_mode_sort);
|
||||
/**
|
||||
* drm_mode_connector_list_update - update the mode list for the connector
|
||||
* @connector: the connector to update
|
||||
* @merge_type_bits: whether to merge or overwrite type bits
|
||||
*
|
||||
* This moves the modes from the @connector probed_modes list
|
||||
* to the actual mode list. It compares the probed mode against the current
|
||||
@ -1180,33 +1180,48 @@ EXPORT_SYMBOL(drm_mode_sort);
|
||||
* This is just a helper functions doesn't validate any modes itself and also
|
||||
* doesn't prune any invalid modes. Callers need to do that themselves.
|
||||
*/
|
||||
void drm_mode_connector_list_update(struct drm_connector *connector,
|
||||
bool merge_type_bits)
|
||||
void drm_mode_connector_list_update(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct drm_display_mode *pmode, *pt;
|
||||
int found_it;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&connector->dev->mode_config.mutex));
|
||||
|
||||
list_for_each_entry_safe(pmode, pt, &connector->probed_modes,
|
||||
head) {
|
||||
found_it = 0;
|
||||
list_for_each_entry_safe(pmode, pt, &connector->probed_modes, head) {
|
||||
struct drm_display_mode *mode;
|
||||
bool found_it = false;
|
||||
|
||||
/* go through current modes checking for the new probed mode */
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
if (drm_mode_equal(pmode, mode)) {
|
||||
found_it = 1;
|
||||
/* if equal delete the probed mode */
|
||||
mode->status = pmode->status;
|
||||
/* Merge type bits together */
|
||||
if (merge_type_bits)
|
||||
mode->type |= pmode->type;
|
||||
else
|
||||
mode->type = pmode->type;
|
||||
list_del(&pmode->head);
|
||||
drm_mode_destroy(connector->dev, pmode);
|
||||
break;
|
||||
if (!drm_mode_equal(pmode, mode))
|
||||
continue;
|
||||
|
||||
found_it = true;
|
||||
|
||||
/*
|
||||
* If the old matching mode is stale (ie. left over
|
||||
* from a previous probe) just replace it outright.
|
||||
* Otherwise just merge the type bits between all
|
||||
* equal probed modes.
|
||||
*
|
||||
* If two probed modes are considered equal, pick the
|
||||
* actual timings from the one that's marked as
|
||||
* preferred (in case the match isn't 100%). If
|
||||
* multiple or zero preferred modes are present, favor
|
||||
* the mode added to the probed_modes list first.
|
||||
*/
|
||||
if (mode->status == MODE_STALE) {
|
||||
drm_mode_copy(mode, pmode);
|
||||
} else if ((mode->type & DRM_MODE_TYPE_PREFERRED) == 0 &&
|
||||
(pmode->type & DRM_MODE_TYPE_PREFERRED) != 0) {
|
||||
pmode->type |= mode->type;
|
||||
drm_mode_copy(mode, pmode);
|
||||
} else {
|
||||
mode->type |= pmode->type;
|
||||
}
|
||||
|
||||
list_del(&pmode->head);
|
||||
drm_mode_destroy(connector->dev, pmode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found_it) {
|
||||
@ -1247,7 +1262,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
|
||||
bool yres_specified = false, cvt = false, rb = false;
|
||||
bool interlace = false, margins = false, was_digit = false;
|
||||
int i, err;
|
||||
int i;
|
||||
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
|
||||
|
||||
#ifdef CONFIG_FB
|
||||
@ -1267,9 +1282,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
case '@':
|
||||
if (!refresh_specified && !bpp_specified &&
|
||||
!yres_specified && !cvt && !rb && was_digit) {
|
||||
err = kstrtouint(&name[i + 1], 10, &refresh);
|
||||
if (err)
|
||||
return false;
|
||||
refresh = simple_strtol(&name[i+1], NULL, 10);
|
||||
refresh_specified = true;
|
||||
was_digit = false;
|
||||
} else
|
||||
@ -1278,9 +1291,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
case '-':
|
||||
if (!bpp_specified && !yres_specified && !cvt &&
|
||||
!rb && was_digit) {
|
||||
err = kstrtouint(&name[i + 1], 10, &bpp);
|
||||
if (err)
|
||||
return false;
|
||||
bpp = simple_strtol(&name[i+1], NULL, 10);
|
||||
bpp_specified = true;
|
||||
was_digit = false;
|
||||
} else
|
||||
@ -1288,9 +1299,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
break;
|
||||
case 'x':
|
||||
if (!yres_specified && was_digit) {
|
||||
err = kstrtouint(&name[i + 1], 10, &yres);
|
||||
if (err)
|
||||
return false;
|
||||
yres = simple_strtol(&name[i+1], NULL, 10);
|
||||
yres_specified = true;
|
||||
was_digit = false;
|
||||
} else
|
||||
@ -1514,4 +1523,4 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -57,6 +57,10 @@
|
||||
* by the atomic helpers.
|
||||
*
|
||||
* Again drivers are strongly urged to switch to the new interfaces.
|
||||
*
|
||||
* The plane helpers share the function table structures with other helpers,
|
||||
* specifically also the atomic helpers. See struct &drm_plane_helper_funcs for
|
||||
* the details.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -371,7 +375,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
|
||||
&drm_primary_helper_funcs,
|
||||
safe_modeset_formats,
|
||||
ARRAY_SIZE(safe_modeset_formats),
|
||||
DRM_PLANE_TYPE_PRIMARY);
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
@ -398,7 +402,8 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
struct drm_plane *primary;
|
||||
|
||||
primary = create_primary_plane(dev);
|
||||
return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs);
|
||||
return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs,
|
||||
NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_init);
|
||||
|
||||
|
@ -53,6 +53,9 @@
|
||||
* This helper library can be used independently of the modeset helper library.
|
||||
* Drivers can also overwrite different parts e.g. use their own hotplug
|
||||
* handling code to avoid probing unrelated outputs.
|
||||
*
|
||||
* The probe helpers share the function table structures with other display
|
||||
* helper libraries. See struct &drm_connector_helper_funcs for the details.
|
||||
*/
|
||||
|
||||
static bool drm_kms_helper_poll = true;
|
||||
@ -126,9 +129,64 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
|
||||
|
||||
|
||||
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY, bool merge_type_bits)
|
||||
/**
|
||||
* drm_helper_probe_single_connector_modes - get complete set of display modes
|
||||
* @connector: connector to probe
|
||||
* @maxX: max width for modes
|
||||
* @maxY: max height for modes
|
||||
*
|
||||
* Based on the helper callbacks implemented by @connector in struct
|
||||
* &drm_connector_helper_funcs try to detect all valid modes. Modes will first
|
||||
* be added to the connector's probed_modes list, then culled (based on validity
|
||||
* and the @maxX, @maxY parameters) and put into the normal modes list.
|
||||
*
|
||||
* Intended to be used as a generic implementation of the ->fill_modes()
|
||||
* @connector vfunc for drivers that use the CRTC helpers for output mode
|
||||
* filtering and detection.
|
||||
*
|
||||
* The basic procedure is as follows
|
||||
*
|
||||
* 1. All modes currently on the connector's modes list are marked as stale
|
||||
*
|
||||
* 2. New modes are added to the connector's probed_modes list with
|
||||
* drm_mode_probed_add(). New modes start their life with status as OK.
|
||||
* Modes are added from a single source using the following priority order.
|
||||
*
|
||||
* - debugfs 'override_edid' (used for testing only)
|
||||
* - firmware EDID (drm_load_edid_firmware())
|
||||
* - connector helper ->get_modes() vfunc
|
||||
* - if the connector status is connector_status_connected, standard
|
||||
* VESA DMT modes up to 1024x768 are automatically added
|
||||
* (drm_add_modes_noedid())
|
||||
*
|
||||
* Finally modes specified via the kernel command line (video=...) are
|
||||
* added in addition to what the earlier probes produced
|
||||
* (drm_helper_probe_add_cmdline_mode()). These modes are generated
|
||||
* using the VESA GTF/CVT formulas.
|
||||
*
|
||||
* 3. Modes are moved from the probed_modes list to the modes list. Potential
|
||||
* duplicates are merged together (see drm_mode_connector_list_update()).
|
||||
* After this step the probed_modes list will be empty again.
|
||||
*
|
||||
* 4. Any non-stale mode on the modes list then undergoes validation
|
||||
*
|
||||
* - drm_mode_validate_basic() performs basic sanity checks
|
||||
* - drm_mode_validate_size() filters out modes larger than @maxX and @maxY
|
||||
* (if specified)
|
||||
* - drm_mode_validate_flag() checks the modes againt basic connector
|
||||
* capabilites (interlace_allowed,doublescan_allowed,stereo_allowed)
|
||||
* - the optional connector ->mode_valid() helper can perform driver and/or
|
||||
* hardware specific checks
|
||||
*
|
||||
* 5. Any mode whose status is not OK is pruned from the connector's modes list,
|
||||
* accompanied by a debug message indicating the reason for the mode's
|
||||
* rejection (see drm_mode_prune_invalid()).
|
||||
*
|
||||
* Returns:
|
||||
* The number of modes found on @connector.
|
||||
*/
|
||||
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode;
|
||||
@ -143,9 +201,9 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
||||
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
|
||||
connector->name);
|
||||
/* set all modes to the unverified state */
|
||||
/* set all old modes to the stale state */
|
||||
list_for_each_entry(mode, &connector->modes, head)
|
||||
mode->status = MODE_UNVERIFIED;
|
||||
mode->status = MODE_STALE;
|
||||
|
||||
old_status = connector->status;
|
||||
|
||||
@ -200,17 +258,16 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
||||
goto prune;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
|
||||
count = drm_load_edid_firmware(connector);
|
||||
if (count == 0)
|
||||
#endif
|
||||
{
|
||||
if (connector->override_edid) {
|
||||
struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
|
||||
if (connector->override_edid) {
|
||||
struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
|
||||
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
drm_edid_to_eld(connector, edid);
|
||||
} else
|
||||
count = drm_add_edid_modes(connector, edid);
|
||||
drm_edid_to_eld(connector, edid);
|
||||
} else {
|
||||
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
|
||||
count = drm_load_edid_firmware(connector);
|
||||
if (count == 0)
|
||||
#endif
|
||||
count = (*connector_funcs->get_modes)(connector);
|
||||
}
|
||||
|
||||
@ -220,7 +277,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
||||
if (count == 0)
|
||||
goto prune;
|
||||
|
||||
drm_mode_connector_list_update(connector, merge_type_bits);
|
||||
drm_mode_connector_list_update(connector);
|
||||
|
||||
if (connector->interlace_allowed)
|
||||
mode_flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
@ -230,7 +287,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
||||
mode_flags |= DRM_MODE_FLAG_3D_MASK;
|
||||
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
mode->status = drm_mode_validate_basic(mode);
|
||||
if (mode->status == MODE_OK)
|
||||
mode->status = drm_mode_validate_basic(mode);
|
||||
|
||||
if (mode->status == MODE_OK)
|
||||
mode->status = drm_mode_validate_size(mode, maxX, maxY);
|
||||
@ -263,48 +321,8 @@ prune:
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_helper_probe_single_connector_modes - get complete set of display modes
|
||||
* @connector: connector to probe
|
||||
* @maxX: max width for modes
|
||||
* @maxY: max height for modes
|
||||
*
|
||||
* Based on the helper callbacks implemented by @connector try to detect all
|
||||
* valid modes. Modes will first be added to the connector's probed_modes list,
|
||||
* then culled (based on validity and the @maxX, @maxY parameters) and put into
|
||||
* the normal modes list.
|
||||
*
|
||||
* Intended to be use as a generic implementation of the ->fill_modes()
|
||||
* @connector vfunc for drivers that use the crtc helpers for output mode
|
||||
* filtering and detection.
|
||||
*
|
||||
* Returns:
|
||||
* The number of modes found on @connector.
|
||||
*/
|
||||
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY)
|
||||
{
|
||||
return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, true);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
|
||||
|
||||
/**
|
||||
* drm_helper_probe_single_connector_modes_nomerge - get complete set of display modes
|
||||
* @connector: connector to probe
|
||||
* @maxX: max width for modes
|
||||
* @maxY: max height for modes
|
||||
*
|
||||
* This operates like drm_hehlper_probe_single_connector_modes except it
|
||||
* replaces the mode bits instead of merging them for preferred modes.
|
||||
*/
|
||||
int drm_helper_probe_single_connector_modes_nomerge(struct drm_connector *connector,
|
||||
uint32_t maxX, uint32_t maxY)
|
||||
{
|
||||
return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, false);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes_nomerge);
|
||||
|
||||
/**
|
||||
* drm_kms_helper_hotplug_event - fire off KMS hotplug events
|
||||
* @dev: drm_device whose connector state changed
|
||||
|
@ -1313,7 +1313,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
|
||||
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
|
||||
|
||||
drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
|
||||
|
||||
|
@ -150,7 +150,7 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
||||
private->crtc[pipe] = crtc;
|
||||
|
||||
ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,
|
||||
&exynos_crtc_funcs);
|
||||
&exynos_crtc_funcs, NULL);
|
||||
if (ret < 0)
|
||||
goto err_crtc;
|
||||
|
||||
|
@ -309,7 +309,7 @@ int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
|
||||
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
|
||||
|
||||
drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
|
||||
|
||||
|
@ -1831,7 +1831,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
|
||||
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
|
||||
|
||||
drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
|
||||
|
||||
|
@ -228,7 +228,7 @@ int exynos_plane_init(struct drm_device *dev,
|
||||
|
||||
err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs,
|
||||
&exynos_plane_funcs, formats, fcount,
|
||||
type);
|
||||
type, NULL);
|
||||
if (err) {
|
||||
DRM_ERROR("failed to initialize plane\n");
|
||||
return err;
|
||||
|
@ -473,7 +473,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
|
||||
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
|
||||
|
||||
drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
|
||||
|
||||
|
@ -1793,7 +1793,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
|
||||
|
||||
drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
|
||||
|
||||
|
@ -175,7 +175,7 @@ int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
|
||||
|
||||
primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
|
||||
ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
|
||||
&fsl_dcu_drm_crtc_funcs);
|
||||
&fsl_dcu_drm_crtc_funcs, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -249,7 +249,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
|
||||
&fsl_dcu_drm_plane_funcs,
|
||||
fsl_dcu_drm_plane_formats,
|
||||
ARRAY_SIZE(fsl_dcu_drm_plane_formats),
|
||||
DRM_PLANE_TYPE_PRIMARY);
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
|
@ -57,7 +57,7 @@ int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
|
||||
|
||||
encoder->possible_crtcs = 1;
|
||||
ret = drm_encoder_init(fsl_dev->drm, encoder, &encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -619,6 +619,8 @@ const struct psb_ops cdv_chip_ops = {
|
||||
.init_pm = cdv_init_pm,
|
||||
.save_regs = cdv_save_display_registers,
|
||||
.restore_regs = cdv_restore_display_registers,
|
||||
.save_crtc = gma_crtc_save,
|
||||
.restore_crtc = gma_crtc_restore,
|
||||
.power_down = cdv_power_down,
|
||||
.power_up = cdv_power_up,
|
||||
.update_wm = cdv_update_wm,
|
||||
|
@ -273,7 +273,7 @@ void cdv_intel_crt_init(struct drm_device *dev,
|
||||
|
||||
encoder = &gma_encoder->base;
|
||||
drm_encoder_init(dev, encoder,
|
||||
&cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
|
||||
&cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
|
||||
|
@ -983,8 +983,6 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
|
||||
};
|
||||
|
||||
const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
|
||||
.save = gma_crtc_save,
|
||||
.restore = gma_crtc_restore,
|
||||
.cursor_set = gma_crtc_cursor_set,
|
||||
.cursor_move = gma_crtc_cursor_move,
|
||||
.gamma_set = gma_crtc_gamma_set,
|
||||
|
@ -2020,7 +2020,8 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
|
||||
encoder = &gma_encoder->base;
|
||||
|
||||
drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, type);
|
||||
drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
|
||||
|
@ -270,8 +270,6 @@ static const struct drm_connector_helper_funcs
|
||||
|
||||
static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = cdv_hdmi_save,
|
||||
.restore = cdv_hdmi_restore,
|
||||
.detect = cdv_hdmi_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = cdv_hdmi_set_property,
|
||||
@ -306,13 +304,16 @@ void cdv_hdmi_init(struct drm_device *dev,
|
||||
|
||||
connector = &gma_connector->base;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
gma_connector->save = cdv_hdmi_save;
|
||||
gma_connector->restore = cdv_hdmi_restore;
|
||||
|
||||
encoder = &gma_encoder->base;
|
||||
drm_connector_init(dev, connector,
|
||||
&cdv_hdmi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DVID);
|
||||
|
||||
drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
gma_encoder->type = INTEL_OUTPUT_HDMI;
|
||||
|
@ -530,8 +530,6 @@ static const struct drm_connector_helper_funcs
|
||||
|
||||
static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = cdv_intel_lvds_save,
|
||||
.restore = cdv_intel_lvds_restore,
|
||||
.detect = cdv_intel_lvds_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = cdv_intel_lvds_set_property,
|
||||
@ -643,6 +641,8 @@ void cdv_intel_lvds_init(struct drm_device *dev,
|
||||
gma_encoder->dev_priv = lvds_priv;
|
||||
|
||||
connector = &gma_connector->base;
|
||||
gma_connector->save = cdv_intel_lvds_save;
|
||||
gma_connector->restore = cdv_intel_lvds_restore;
|
||||
encoder = &gma_encoder->base;
|
||||
|
||||
|
||||
@ -652,7 +652,7 @@ void cdv_intel_lvds_init(struct drm_device *dev,
|
||||
|
||||
drm_encoder_init(dev, encoder,
|
||||
&cdv_intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
|
@ -546,6 +546,8 @@ const struct psb_ops mdfld_chip_ops = {
|
||||
|
||||
.save_regs = mdfld_save_registers,
|
||||
.restore_regs = mdfld_restore_registers,
|
||||
.save_crtc = gma_crtc_save,
|
||||
.restore_crtc = gma_crtc_restore,
|
||||
.power_down = mdfld_power_down,
|
||||
.power_up = mdfld_power_up,
|
||||
};
|
||||
|
@ -994,7 +994,7 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
|
||||
drm_encoder_init(dev,
|
||||
encoder,
|
||||
p_funcs->encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
drm_encoder_helper_add(encoder,
|
||||
p_funcs->encoder_helper_funcs);
|
||||
|
||||
|
@ -405,8 +405,6 @@ static struct drm_encoder *mdfld_dsi_connector_best_encoder(
|
||||
/*DSI connector funcs*/
|
||||
static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
|
||||
.dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
|
||||
.save = mdfld_dsi_connector_save,
|
||||
.restore = mdfld_dsi_connector_restore,
|
||||
.detect = mdfld_dsi_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = mdfld_dsi_connector_set_property,
|
||||
@ -563,6 +561,9 @@ void mdfld_dsi_output_init(struct drm_device *dev,
|
||||
|
||||
|
||||
connector = &dsi_connector->base.base;
|
||||
dsi_connector->base.save = mdfld_dsi_connector_save;
|
||||
dsi_connector->base.restore = mdfld_dsi_connector_restore;
|
||||
|
||||
drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
|
||||
|
@ -568,6 +568,8 @@ const struct psb_ops oaktrail_chip_ops = {
|
||||
|
||||
.save_regs = oaktrail_save_display_registers,
|
||||
.restore_regs = oaktrail_restore_display_registers,
|
||||
.save_crtc = gma_crtc_save,
|
||||
.restore_crtc = gma_crtc_restore,
|
||||
.power_down = oaktrail_power_down,
|
||||
.power_up = oaktrail_power_up,
|
||||
|
||||
|
@ -654,7 +654,7 @@ void oaktrail_hdmi_init(struct drm_device *dev,
|
||||
|
||||
drm_encoder_init(dev, encoder,
|
||||
&oaktrail_hdmi_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
|
||||
|
@ -323,7 +323,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
||||
drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
gma_encoder->type = INTEL_OUTPUT_LVDS;
|
||||
|
@ -181,7 +181,7 @@ static int psb_save_display_registers(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct gma_connector *connector;
|
||||
struct psb_state *regs = &dev_priv->regs.psb;
|
||||
|
||||
/* Display arbitration control + watermarks */
|
||||
@ -198,12 +198,12 @@ static int psb_save_display_registers(struct drm_device *dev)
|
||||
drm_modeset_lock_all(dev);
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (drm_helper_crtc_in_use(crtc))
|
||||
crtc->funcs->save(crtc);
|
||||
dev_priv->ops->save_crtc(crtc);
|
||||
}
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||
if (connector->funcs->save)
|
||||
connector->funcs->save(connector);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, base.head)
|
||||
if (connector->save)
|
||||
connector->save(&connector->base);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
return 0;
|
||||
@ -219,7 +219,7 @@ static int psb_restore_display_registers(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct gma_connector *connector;
|
||||
struct psb_state *regs = &dev_priv->regs.psb;
|
||||
|
||||
/* Display arbitration + watermarks */
|
||||
@ -238,11 +238,11 @@ static int psb_restore_display_registers(struct drm_device *dev)
|
||||
drm_modeset_lock_all(dev);
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
if (drm_helper_crtc_in_use(crtc))
|
||||
crtc->funcs->restore(crtc);
|
||||
dev_priv->ops->restore_crtc(crtc);
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||
if (connector->funcs->restore)
|
||||
connector->funcs->restore(connector);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, base.head)
|
||||
if (connector->restore)
|
||||
connector->restore(&connector->base);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
return 0;
|
||||
@ -354,6 +354,8 @@ const struct psb_ops psb_chip_ops = {
|
||||
.init_pm = psb_init_pm,
|
||||
.save_regs = psb_save_display_registers,
|
||||
.restore_regs = psb_restore_display_registers,
|
||||
.save_crtc = gma_crtc_save,
|
||||
.restore_crtc = gma_crtc_restore,
|
||||
.power_down = psb_power_down,
|
||||
.power_up = psb_power_up,
|
||||
};
|
||||
|
@ -653,6 +653,8 @@ struct psb_ops {
|
||||
void (*init_pm)(struct drm_device *dev);
|
||||
int (*save_regs)(struct drm_device *dev);
|
||||
int (*restore_regs)(struct drm_device *dev);
|
||||
void (*save_crtc)(struct drm_crtc *crtc);
|
||||
void (*restore_crtc)(struct drm_crtc *crtc);
|
||||
int (*power_up)(struct drm_device *dev);
|
||||
int (*power_down)(struct drm_device *dev);
|
||||
void (*update_wm)(struct drm_device *dev, struct drm_crtc *crtc);
|
||||
|
@ -439,8 +439,6 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
|
||||
};
|
||||
|
||||
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
|
||||
.save = gma_crtc_save,
|
||||
.restore = gma_crtc_restore,
|
||||
.cursor_set = gma_crtc_cursor_set,
|
||||
.cursor_move = gma_crtc_cursor_move,
|
||||
.gamma_set = gma_crtc_gamma_set,
|
||||
|
@ -140,6 +140,9 @@ struct gma_encoder {
|
||||
struct gma_connector {
|
||||
struct drm_connector base;
|
||||
struct gma_encoder *encoder;
|
||||
|
||||
void (*save)(struct drm_connector *connector);
|
||||
void (*restore)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
struct psb_intel_crtc_state {
|
||||
|
@ -653,8 +653,6 @@ const struct drm_connector_helper_funcs
|
||||
|
||||
const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = psb_intel_lvds_save,
|
||||
.restore = psb_intel_lvds_restore,
|
||||
.detect = psb_intel_lvds_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = psb_intel_lvds_set_property,
|
||||
@ -715,6 +713,9 @@ void psb_intel_lvds_init(struct drm_device *dev,
|
||||
gma_encoder->dev_priv = lvds_priv;
|
||||
|
||||
connector = &gma_connector->base;
|
||||
gma_connector->save = psb_intel_lvds_save;
|
||||
gma_connector->restore = psb_intel_lvds_restore;
|
||||
|
||||
encoder = &gma_encoder->base;
|
||||
drm_connector_init(dev, connector,
|
||||
&psb_intel_lvds_connector_funcs,
|
||||
@ -722,7 +723,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
|
||||
|
||||
drm_encoder_init(dev, encoder,
|
||||
&psb_intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
|
||||
gma_connector_attach_encoder(gma_connector, gma_encoder);
|
||||
gma_encoder->type = INTEL_OUTPUT_LVDS;
|
||||
|
@ -1837,8 +1837,6 @@ static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
|
||||
|
||||
static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = psb_intel_sdvo_save,
|
||||
.restore = psb_intel_sdvo_restore,
|
||||
.detect = psb_intel_sdvo_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = psb_intel_sdvo_set_property,
|
||||
@ -2021,6 +2019,9 @@ psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector,
|
||||
connector->base.base.doublescan_allowed = 0;
|
||||
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
|
||||
connector->base.save = psb_intel_sdvo_save;
|
||||
connector->base.restore = psb_intel_sdvo_restore;
|
||||
|
||||
gma_connector_attach_encoder(&connector->base, &encoder->base);
|
||||
drm_connector_register(&connector->base.base);
|
||||
}
|
||||
@ -2525,7 +2526,8 @@ bool psb_intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
|
||||
/* encoder type will be decided later */
|
||||
gma_encoder = &psb_intel_sdvo->base;
|
||||
gma_encoder->type = INTEL_OUTPUT_SDVO;
|
||||
drm_encoder_init(dev, &gma_encoder->base, &psb_intel_sdvo_enc_funcs, 0);
|
||||
drm_encoder_init(dev, &gma_encoder->base, &psb_intel_sdvo_enc_funcs,
|
||||
0, NULL);
|
||||
|
||||
/* Read the regs to test if we can talk to the device */
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
|
@ -855,18 +855,6 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
priv->dpms = mode;
|
||||
}
|
||||
|
||||
static void
|
||||
tda998x_encoder_save(struct drm_encoder *encoder)
|
||||
{
|
||||
DBG("");
|
||||
}
|
||||
|
||||
static void
|
||||
tda998x_encoder_restore(struct drm_encoder *encoder)
|
||||
{
|
||||
DBG("");
|
||||
}
|
||||
|
||||
static bool
|
||||
tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
@ -1351,8 +1339,6 @@ static void tda998x_encoder_commit(struct drm_encoder *encoder)
|
||||
|
||||
static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
|
||||
.dpms = tda998x_encoder_dpms,
|
||||
.save = tda998x_encoder_save,
|
||||
.restore = tda998x_encoder_restore,
|
||||
.mode_fixup = tda998x_encoder_mode_fixup,
|
||||
.prepare = tda998x_encoder_prepare,
|
||||
.commit = tda998x_encoder_commit,
|
||||
@ -1437,7 +1423,7 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
|
||||
|
||||
drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs);
|
||||
ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
if (ret)
|
||||
goto err_encoder;
|
||||
|
||||
|
@ -2949,6 +2949,10 @@ i915_gem_idle_work_handler(struct work_struct *work)
|
||||
if (!list_empty(&ring->request_list))
|
||||
return;
|
||||
|
||||
/* we probably should sync with hangcheck here, using cancel_work_sync.
|
||||
* Also locking seems to be fubar here, ring->request_list is protected
|
||||
* by dev->struct_mutex. */
|
||||
|
||||
intel_mark_idle(dev);
|
||||
|
||||
if (mutex_trylock(&dev->struct_mutex)) {
|
||||
|
@ -798,7 +798,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
|
||||
|
||||
drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
|
||||
intel_connector_attach_encoder(intel_connector, &crt->base);
|
||||
|
||||
|
@ -3284,7 +3284,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
|
||||
encoder = &intel_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &intel_ddi_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
intel_encoder->compute_config = intel_ddi_compute_config;
|
||||
intel_encoder->enable = intel_enable_ddi;
|
||||
|
@ -13904,7 +13904,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
|
||||
drm_universal_plane_init(dev, &primary->base, 0,
|
||||
&intel_plane_funcs,
|
||||
intel_primary_formats, num_formats,
|
||||
DRM_PLANE_TYPE_PRIMARY);
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4)
|
||||
intel_create_rotation_property(dev, primary);
|
||||
@ -14043,7 +14043,7 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
|
||||
&intel_plane_funcs,
|
||||
intel_cursor_formats,
|
||||
ARRAY_SIZE(intel_cursor_formats),
|
||||
DRM_PLANE_TYPE_CURSOR);
|
||||
DRM_PLANE_TYPE_CURSOR, NULL);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
if (!dev->mode_config.rotation_property)
|
||||
@ -14120,7 +14120,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
goto fail;
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
|
||||
cursor, &intel_crtc_funcs);
|
||||
cursor, &intel_crtc_funcs, NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
@ -5977,7 +5977,7 @@ intel_dp_init(struct drm_device *dev,
|
||||
encoder = &intel_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
intel_encoder->compute_config = intel_dp_compute_config;
|
||||
intel_encoder->disable = intel_disable_dp;
|
||||
|
@ -536,7 +536,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
|
||||
intel_mst->primary = intel_dig_port;
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_dp_mst_enc_funcs,
|
||||
DRM_MODE_ENCODER_DPMST);
|
||||
DRM_MODE_ENCODER_DPMST, NULL);
|
||||
|
||||
intel_encoder->type = INTEL_OUTPUT_DP_MST;
|
||||
intel_encoder->crtc_mask = 0x7;
|
||||
|
@ -1152,7 +1152,8 @@ void intel_dsi_init(struct drm_device *dev)
|
||||
|
||||
connector = &intel_connector->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI);
|
||||
drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
|
||||
NULL);
|
||||
|
||||
/* XXX: very likely not all of these are needed */
|
||||
intel_encoder->compute_config = intel_dsi_compute_config;
|
||||
|
@ -429,7 +429,7 @@ void intel_dvo_init(struct drm_device *dev)
|
||||
|
||||
intel_encoder = &intel_dvo->base;
|
||||
drm_encoder_init(dev, &intel_encoder->base,
|
||||
&intel_dvo_enc_funcs, encoder_type);
|
||||
&intel_dvo_enc_funcs, encoder_type, NULL);
|
||||
|
||||
intel_encoder->disable = intel_disable_dvo;
|
||||
intel_encoder->enable = intel_enable_dvo;
|
||||
|
@ -2165,7 +2165,7 @@ void intel_hdmi_init(struct drm_device *dev,
|
||||
intel_encoder = &intel_dig_port->base;
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
intel_encoder->compute_config = intel_hdmi_compute_config;
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
|
@ -1025,7 +1025,7 @@ void intel_lvds_init(struct drm_device *dev)
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
|
||||
intel_encoder->enable = intel_enable_lvds;
|
||||
intel_encoder->pre_enable = intel_pre_enable_lvds;
|
||||
|
@ -2978,7 +2978,8 @@ bool intel_sdvo_init(struct drm_device *dev,
|
||||
/* encoder type will be decided later */
|
||||
intel_encoder = &intel_sdvo->base;
|
||||
intel_encoder->type = INTEL_OUTPUT_SDVO;
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0,
|
||||
NULL);
|
||||
|
||||
/* Read the regs to test if we can talk to the device */
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
|
@ -1123,7 +1123,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
|
||||
ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
|
||||
&intel_plane_funcs,
|
||||
plane_formats, num_plane_formats,
|
||||
DRM_PLANE_TYPE_OVERLAY);
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
if (ret) {
|
||||
kfree(intel_plane);
|
||||
goto out;
|
||||
|
@ -1645,7 +1645,7 @@ intel_tv_init(struct drm_device *dev)
|
||||
DRM_MODE_CONNECTOR_SVIDEO);
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
|
||||
DRM_MODE_ENCODER_TVDAC);
|
||||
DRM_MODE_ENCODER_TVDAC, NULL);
|
||||
|
||||
intel_encoder->compute_config = intel_tv_compute_config;
|
||||
intel_encoder->get_config = intel_tv_get_config;
|
||||
|
@ -251,7 +251,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
|
||||
|
||||
drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
|
||||
drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
|
||||
return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
|
||||
imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
|
||||
|
||||
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
|
||||
imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
|
||||
imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs, NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -422,7 +422,7 @@ static int imx_ldb_register(struct drm_device *drm,
|
||||
drm_encoder_helper_add(&imx_ldb_ch->encoder,
|
||||
&imx_ldb_encoder_helper_funcs);
|
||||
drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
|
||||
drm_connector_helper_add(&imx_ldb_ch->connector,
|
||||
&imx_ldb_connector_helper_funcs);
|
||||
|
@ -508,7 +508,7 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
|
||||
|
||||
drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
|
||||
drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs,
|
||||
encoder_type);
|
||||
encoder_type, NULL);
|
||||
|
||||
drm_connector_helper_add(&tve->connector,
|
||||
&imx_tve_connector_helper_funcs);
|
||||
|
@ -401,7 +401,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
|
||||
|
||||
ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
|
||||
&ipu_plane_funcs, ipu_plane_formats,
|
||||
ARRAY_SIZE(ipu_plane_formats), type);
|
||||
ARRAY_SIZE(ipu_plane_formats), type,
|
||||
NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to initialize plane\n");
|
||||
kfree(ipu_plane);
|
||||
|
@ -192,7 +192,7 @@ static int imx_pd_register(struct drm_device *drm,
|
||||
|
||||
drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
|
||||
drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs,
|
||||
DRM_MODE_ENCODER_NONE);
|
||||
DRM_MODE_ENCODER_NONE, NULL);
|
||||
|
||||
drm_connector_helper_add(&imxpd->connector,
|
||||
&imx_pd_connector_helper_funcs);
|
||||
|
@ -1538,7 +1538,7 @@ static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
|
||||
encoder->possible_crtcs = 0x1;
|
||||
|
||||
drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DAC);
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
|
||||
|
||||
return encoder;
|
||||
|
@ -678,7 +678,8 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
|
||||
drm_flip_work_init(&mdp4_crtc->unref_cursor_work,
|
||||
"unref cursor", unref_cursor_worker);
|
||||
|
||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs);
|
||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs,
|
||||
NULL);
|
||||
drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
|
||||
plane->crtc = crtc;
|
||||
|
||||
|
@ -185,7 +185,7 @@ struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
|
||||
encoder = &mdp4_dsi_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &mdp4_dsi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DSI);
|
||||
DRM_MODE_ENCODER_DSI, NULL);
|
||||
drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs);
|
||||
|
||||
return encoder;
|
||||
|
@ -262,7 +262,7 @@ struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev)
|
||||
encoder = &mdp4_dtv_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs);
|
||||
|
||||
mdp4_dtv_encoder->src_clk = devm_clk_get(dev->dev, "src_clk");
|
||||
|
@ -463,7 +463,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
|
||||
encoder = &mdp4_lcdc_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &mdp4_lcdc_encoder_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs);
|
||||
|
||||
/* TODO: do we need different pll in other cases? */
|
||||
|
@ -397,7 +397,8 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
|
||||
|
||||
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
||||
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
|
||||
mdp4_plane->formats, mdp4_plane->nformats, type);
|
||||
mdp4_plane->formats, mdp4_plane->nformats,
|
||||
type, NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
@ -326,7 +326,7 @@ struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
|
||||
mdp5_cmd_enc->ctl = ctl;
|
||||
|
||||
drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DSI);
|
||||
DRM_MODE_ENCODER_DSI, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &mdp5_cmd_encoder_helper_funcs);
|
||||
|
||||
|
@ -797,7 +797,8 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
|
||||
snprintf(mdp5_crtc->name, sizeof(mdp5_crtc->name), "%s:%d",
|
||||
pipe2name(mdp5_plane_pipe(plane)), id);
|
||||
|
||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs);
|
||||
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs,
|
||||
NULL);
|
||||
|
||||
drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
|
||||
"unref cursor", unref_cursor_worker);
|
||||
|
@ -372,7 +372,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
|
||||
|
||||
spin_lock_init(&mdp5_encoder->intf_lock);
|
||||
|
||||
drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type);
|
||||
drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type, NULL);
|
||||
|
||||
drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs);
|
||||
|
||||
|
@ -904,7 +904,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
|
||||
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
||||
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
|
||||
mdp5_plane->formats, mdp5_plane->nformats,
|
||||
type);
|
||||
type, NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
@ -1081,8 +1081,6 @@ nouveau_crtc_set_config(struct drm_mode_set *set)
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs nv04_crtc_funcs = {
|
||||
.save = nv_crtc_save,
|
||||
.restore = nv_crtc_restore,
|
||||
.cursor_set = nv04_crtc_cursor_set,
|
||||
.cursor_move = nv04_crtc_cursor_move,
|
||||
.gamma_set = nv_crtc_gamma_set,
|
||||
@ -1123,6 +1121,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
||||
nv_crtc->index = crtc_num;
|
||||
nv_crtc->last_dpms = NV_DPMS_CLEARED;
|
||||
|
||||
nv_crtc->save = nv_crtc_save;
|
||||
nv_crtc->restore = nv_crtc_restore;
|
||||
|
||||
drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
|
||||
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
|
||||
|
@ -504,8 +504,6 @@ static void nv04_dac_destroy(struct drm_encoder *encoder)
|
||||
|
||||
static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = {
|
||||
.dpms = nv04_dac_dpms,
|
||||
.save = nv04_dac_save,
|
||||
.restore = nv04_dac_restore,
|
||||
.mode_fixup = nv04_dac_mode_fixup,
|
||||
.prepare = nv04_dac_prepare,
|
||||
.commit = nv04_dac_commit,
|
||||
@ -515,8 +513,6 @@ static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = {
|
||||
|
||||
static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = {
|
||||
.dpms = nv04_dac_dpms,
|
||||
.save = nv04_dac_save,
|
||||
.restore = nv04_dac_restore,
|
||||
.mode_fixup = nv04_dac_mode_fixup,
|
||||
.prepare = nv04_dac_prepare,
|
||||
.commit = nv04_dac_commit,
|
||||
@ -545,12 +541,16 @@ nv04_dac_create(struct drm_connector *connector, struct dcb_output *entry)
|
||||
nv_encoder->dcb = entry;
|
||||
nv_encoder->or = ffs(entry->or) - 1;
|
||||
|
||||
nv_encoder->enc_save = nv04_dac_save;
|
||||
nv_encoder->enc_restore = nv04_dac_restore;
|
||||
|
||||
if (nv_gf4_disp_arch(dev))
|
||||
helper = &nv17_dac_helper_funcs;
|
||||
else
|
||||
helper = &nv04_dac_helper_funcs;
|
||||
|
||||
drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC);
|
||||
drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC,
|
||||
NULL);
|
||||
drm_encoder_helper_add(encoder, helper);
|
||||
|
||||
encoder->possible_crtcs = entry->heads;
|
||||
|
@ -652,8 +652,6 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
|
||||
|
||||
static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
|
||||
.dpms = nv04_lvds_dpms,
|
||||
.save = nv04_dfp_save,
|
||||
.restore = nv04_dfp_restore,
|
||||
.mode_fixup = nv04_dfp_mode_fixup,
|
||||
.prepare = nv04_dfp_prepare,
|
||||
.commit = nv04_dfp_commit,
|
||||
@ -663,8 +661,6 @@ static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
|
||||
|
||||
static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = {
|
||||
.dpms = nv04_tmds_dpms,
|
||||
.save = nv04_dfp_save,
|
||||
.restore = nv04_dfp_restore,
|
||||
.mode_fixup = nv04_dfp_mode_fixup,
|
||||
.prepare = nv04_dfp_prepare,
|
||||
.commit = nv04_dfp_commit,
|
||||
@ -701,12 +697,15 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_output *entry)
|
||||
if (!nv_encoder)
|
||||
return -ENOMEM;
|
||||
|
||||
nv_encoder->enc_save = nv04_dfp_save;
|
||||
nv_encoder->enc_restore = nv04_dfp_restore;
|
||||
|
||||
encoder = to_drm_encoder(nv_encoder);
|
||||
|
||||
nv_encoder->dcb = entry;
|
||||
nv_encoder->or = ffs(entry->or) - 1;
|
||||
|
||||
drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
|
||||
drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type, NULL);
|
||||
drm_encoder_helper_add(encoder, helper);
|
||||
|
||||
encoder->possible_crtcs = entry->heads;
|
||||
|
@ -39,7 +39,8 @@ nv04_display_create(struct drm_device *dev)
|
||||
struct dcb_table *dcb = &drm->vbios.dcb;
|
||||
struct drm_connector *connector, *ct;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_crtc *crtc;
|
||||
struct nouveau_encoder *nv_encoder;
|
||||
struct nouveau_crtc *crtc;
|
||||
struct nv04_display *disp;
|
||||
int i, ret;
|
||||
|
||||
@ -107,14 +108,11 @@ nv04_display_create(struct drm_device *dev)
|
||||
}
|
||||
|
||||
/* Save previous state */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
crtc->funcs->save(crtc);
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
|
||||
crtc->save(&crtc->base);
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
const struct drm_encoder_helper_funcs *func = encoder->helper_private;
|
||||
|
||||
func->save(encoder);
|
||||
}
|
||||
list_for_each_entry(nv_encoder, &dev->mode_config.encoder_list, base.base.head)
|
||||
nv_encoder->enc_save(&nv_encoder->base.base);
|
||||
|
||||
nouveau_overlay_init(dev);
|
||||
|
||||
@ -126,8 +124,9 @@ nv04_display_destroy(struct drm_device *dev)
|
||||
{
|
||||
struct nv04_display *disp = nv04_display(dev);
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
struct drm_encoder *encoder;
|
||||
struct nouveau_encoder *encoder;
|
||||
struct drm_crtc *crtc;
|
||||
struct nouveau_crtc *nv_crtc;
|
||||
|
||||
/* Turn every CRTC off. */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
@ -139,14 +138,11 @@ nv04_display_destroy(struct drm_device *dev)
|
||||
}
|
||||
|
||||
/* Restore state */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
const struct drm_encoder_helper_funcs *func = encoder->helper_private;
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
|
||||
encoder->enc_restore(&encoder->base.base);
|
||||
|
||||
func->restore(encoder);
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
crtc->funcs->restore(crtc);
|
||||
list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
|
||||
nv_crtc->restore(&nv_crtc->base);
|
||||
|
||||
nouveau_hw_save_vga_fonts(dev, 0);
|
||||
|
||||
@ -159,8 +155,8 @@ nv04_display_destroy(struct drm_device *dev)
|
||||
int
|
||||
nv04_display_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_crtc *crtc;
|
||||
struct nouveau_encoder *encoder;
|
||||
struct nouveau_crtc *crtc;
|
||||
|
||||
/* meh.. modeset apparently doesn't setup all the regs and depends
|
||||
* on pre-existing state, for now load the state of the card *before*
|
||||
@ -170,14 +166,11 @@ nv04_display_init(struct drm_device *dev)
|
||||
* save/restore "pre-load" state, but more general so we can save
|
||||
* on suspend too.
|
||||
*/
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
const struct drm_encoder_helper_funcs *func = encoder->helper_private;
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
|
||||
crtc->save(&crtc->base);
|
||||
|
||||
func->restore(encoder);
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
crtc->funcs->restore(crtc);
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
|
||||
encoder->enc_save(&encoder->base.base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -192,8 +192,6 @@ static const struct drm_encoder_funcs nv04_tv_funcs = {
|
||||
|
||||
static const struct drm_encoder_helper_funcs nv04_tv_helper_funcs = {
|
||||
.dpms = nv04_tv_dpms,
|
||||
.save = drm_i2c_encoder_save,
|
||||
.restore = drm_i2c_encoder_restore,
|
||||
.mode_fixup = drm_i2c_encoder_mode_fixup,
|
||||
.prepare = nv04_tv_prepare,
|
||||
.commit = nv04_tv_commit,
|
||||
@ -225,9 +223,13 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry)
|
||||
/* Initialize the common members */
|
||||
encoder = to_drm_encoder(nv_encoder);
|
||||
|
||||
drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC);
|
||||
drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC,
|
||||
NULL);
|
||||
drm_encoder_helper_add(encoder, &nv04_tv_helper_funcs);
|
||||
|
||||
nv_encoder->enc_save = drm_i2c_encoder_save;
|
||||
nv_encoder->enc_restore = drm_i2c_encoder_restore;
|
||||
|
||||
encoder->possible_crtcs = entry->heads;
|
||||
encoder->possible_clones = 0;
|
||||
nv_encoder->dcb = entry;
|
||||
|
@ -771,8 +771,6 @@ static void nv17_tv_destroy(struct drm_encoder *encoder)
|
||||
|
||||
static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = {
|
||||
.dpms = nv17_tv_dpms,
|
||||
.save = nv17_tv_save,
|
||||
.restore = nv17_tv_restore,
|
||||
.mode_fixup = nv17_tv_mode_fixup,
|
||||
.prepare = nv17_tv_prepare,
|
||||
.commit = nv17_tv_commit,
|
||||
@ -816,10 +814,14 @@ nv17_tv_create(struct drm_connector *connector, struct dcb_output *entry)
|
||||
tv_enc->base.dcb = entry;
|
||||
tv_enc->base.or = ffs(entry->or) - 1;
|
||||
|
||||
drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC);
|
||||
drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC,
|
||||
NULL);
|
||||
drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs);
|
||||
to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs;
|
||||
|
||||
tv_enc->base.enc_save = nv17_tv_save;
|
||||
tv_enc->base.enc_restore = nv17_tv_restore;
|
||||
|
||||
encoder->possible_crtcs = entry->heads;
|
||||
encoder->possible_clones = 0;
|
||||
|
||||
|
@ -898,8 +898,6 @@ nouveau_connector_helper_funcs = {
|
||||
static const struct drm_connector_funcs
|
||||
nouveau_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = NULL,
|
||||
.restore = NULL,
|
||||
.detect = nouveau_connector_detect,
|
||||
.destroy = nouveau_connector_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
@ -910,8 +908,6 @@ nouveau_connector_funcs = {
|
||||
static const struct drm_connector_funcs
|
||||
nouveau_connector_funcs_lvds = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = NULL,
|
||||
.restore = NULL,
|
||||
.detect = nouveau_connector_detect_lvds,
|
||||
.destroy = nouveau_connector_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
@ -944,8 +940,6 @@ nouveau_connector_dp_dpms(struct drm_connector *connector, int mode)
|
||||
static const struct drm_connector_funcs
|
||||
nouveau_connector_funcs_dp = {
|
||||
.dpms = nouveau_connector_dp_dpms,
|
||||
.save = NULL,
|
||||
.restore = NULL,
|
||||
.detect = nouveau_connector_detect,
|
||||
.destroy = nouveau_connector_destroy,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
|
@ -73,6 +73,9 @@ struct nouveau_crtc {
|
||||
int (*set_dither)(struct nouveau_crtc *crtc, bool update);
|
||||
int (*set_scale)(struct nouveau_crtc *crtc, bool update);
|
||||
int (*set_color_vibrance)(struct nouveau_crtc *crtc, bool update);
|
||||
|
||||
void (*save)(struct drm_crtc *crtc);
|
||||
void (*restore)(struct drm_crtc *crtc);
|
||||
};
|
||||
|
||||
static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc)
|
||||
|
@ -63,6 +63,9 @@ struct nouveau_encoder {
|
||||
u32 datarate;
|
||||
} dp;
|
||||
};
|
||||
|
||||
void (*enc_save)(struct drm_encoder *encoder);
|
||||
void (*enc_restore)(struct drm_encoder *encoder);
|
||||
};
|
||||
|
||||
struct nouveau_encoder *
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
@ -1717,7 +1718,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
||||
encoder = to_drm_encoder(nv_encoder);
|
||||
encoder->possible_crtcs = dcbe->heads;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type);
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, NULL);
|
||||
drm_encoder_helper_add(encoder, &nv50_dac_hfunc);
|
||||
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
@ -2125,7 +2126,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
||||
encoder = to_drm_encoder(nv_encoder);
|
||||
encoder->possible_crtcs = dcbe->heads;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type);
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, NULL);
|
||||
drm_encoder_helper_add(encoder, &nv50_sor_hfunc);
|
||||
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
@ -2305,7 +2306,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
||||
encoder = to_drm_encoder(nv_encoder);
|
||||
encoder->possible_crtcs = dcbe->heads;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type);
|
||||
drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, NULL);
|
||||
drm_encoder_helper_add(encoder, &nv50_pior_hfunc);
|
||||
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
|
@ -524,7 +524,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
||||
omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
||||
&omap_crtc_funcs);
|
||||
&omap_crtc_funcs, NULL);
|
||||
if (ret < 0) {
|
||||
kfree(omap_crtc);
|
||||
return NULL;
|
||||
|
@ -178,7 +178,7 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev,
|
||||
encoder = &omap_encoder->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &omap_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
|
||||
|
||||
return encoder;
|
||||
|
@ -366,7 +366,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
|
||||
|
||||
ret = drm_universal_plane_init(dev, plane, (1 << priv->num_crtcs) - 1,
|
||||
&omap_plane_funcs, omap_plane->formats,
|
||||
omap_plane->nformats, type);
|
||||
omap_plane->nformats, type, NULL);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
|
@ -876,16 +876,6 @@ static const struct drm_connector_helper_funcs qxl_connector_helper_funcs = {
|
||||
.best_encoder = qxl_best_encoder,
|
||||
};
|
||||
|
||||
static void qxl_conn_save(struct drm_connector *connector)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
}
|
||||
|
||||
static void qxl_conn_restore(struct drm_connector *connector)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
}
|
||||
|
||||
static enum drm_connector_status qxl_conn_detect(
|
||||
struct drm_connector *connector,
|
||||
bool force)
|
||||
@ -932,10 +922,8 @@ static void qxl_conn_destroy(struct drm_connector *connector)
|
||||
|
||||
static const struct drm_connector_funcs qxl_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.save = qxl_conn_save,
|
||||
.restore = qxl_conn_restore,
|
||||
.detect = qxl_conn_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes_nomerge,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = qxl_conn_set_property,
|
||||
.destroy = qxl_conn_destroy,
|
||||
};
|
||||
@ -980,7 +968,7 @@ static int qdev_output_init(struct drm_device *dev, int num_output)
|
||||
&qxl_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL);
|
||||
|
||||
drm_encoder_init(dev, &qxl_output->enc, &qxl_enc_funcs,
|
||||
DRM_MODE_ENCODER_VIRTUAL);
|
||||
DRM_MODE_ENCODER_VIRTUAL, NULL);
|
||||
|
||||
/* we get HPD via client monitors config */
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
#include <drm/drm_fixed.h>
|
||||
#include "radeon.h"
|
||||
|
@ -2767,23 +2767,27 @@ radeon_add_atom_encoder(struct drm_device *dev,
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
radeon_encoder->rmx_type = RMX_FULL;
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
|
||||
} else {
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
|
||||
}
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_TVDAC, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
|
||||
break;
|
||||
@ -2797,13 +2801,16 @@ radeon_add_atom_encoder(struct drm_device *dev,
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
radeon_encoder->rmx_type = RMX_FULL;
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
|
||||
} else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
|
||||
} else {
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
|
||||
}
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
|
||||
@ -2820,11 +2827,14 @@ radeon_add_atom_encoder(struct drm_device *dev,
|
||||
/* these are handled by the primary encoders */
|
||||
radeon_encoder->is_ext_encoder = true;
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
else
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
|
||||
break;
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector)
|
||||
}
|
||||
|
||||
drm_encoder_init(dev, &radeon_encoder->base, &radeon_dp_mst_enc_funcs,
|
||||
DRM_MODE_ENCODER_DPMST);
|
||||
DRM_MODE_ENCODER_DPMST, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_mst_helper_funcs);
|
||||
|
||||
mst_enc = radeon_encoder->enc_priv;
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
#include <drm/drm_fixed.h>
|
||||
#include "radeon.h"
|
||||
|
@ -1772,7 +1772,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
||||
encoder->possible_crtcs = 0x1;
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
|
||||
@ -1781,12 +1782,14 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
|
||||
radeon_encoder->rmx_type = RMX_FULL;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
|
||||
radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs,
|
||||
DRM_MODE_ENCODER_DAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs);
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder);
|
||||
@ -1794,7 +1797,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
|
||||
radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC);
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs,
|
||||
DRM_MODE_ENCODER_TVDAC, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder);
|
||||
@ -1802,7 +1806,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_
|
||||
radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS, NULL);
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs);
|
||||
if (!rdev->is_atom_bios)
|
||||
radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder);
|
||||
|
@ -613,7 +613,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
|
||||
|
||||
ret = drm_crtc_init_with_planes(rcdu->ddev, crtc,
|
||||
&rgrp->planes[index % 2].plane,
|
||||
NULL, &crtc_funcs);
|
||||
NULL, &crtc_funcs, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -173,7 +173,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
||||
goto done;
|
||||
} else {
|
||||
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
|
||||
encoder_type);
|
||||
encoder_type, NULL);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user