linux/include/drm/drm_bridge.h

677 lines
25 KiB
C
Raw Normal View History

/*
* Copyright (c) 2016 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef __DRM_BRIDGE_H__
#define __DRM_BRIDGE_H__
#include <linux/list.h>
#include <linux/ctype.h>
drm/bridge: Add a drm_bridge_state object One of the last remaining objects to not have its atomic state. This is being motivated by our attempt to support runtime bus-format negotiation between elements of the bridge chain. This patch just paves the road for such a feature by adding a new drm_bridge_state object inheriting from drm_private_obj so we can re-use some of the existing state initialization/tracking logic. v10: * Add changelog to the commit message v9: * Clarify the fact that the bridge->atomic_reset() and {connector,plane,crtc,...}->reset() semantics are different * Move the drm_atomic_private_obj_init() call back to drm_bridge_attach() * Check the presence of ->atomic_duplicate_state instead of ->atomic_reset in drm_atomic_add_encoder_bridges() * Fix copy&paste errors in the atomic bridge state helpers doc * Add A-b/R-b tags v8: * Move bridge state helpers out of the CONFIG_DEBUGFS section v7: * Move helpers, struct-defs, ... to atomic helper files to avoid the drm -> drm_kms_helper -> drm circular dep * Stop providing default implementation for atomic state reset, duplicate and destroy hooks (has to do with the helper/core split) * Drop all R-b/T-b as helpers have now be moved to other places v6: * Made helpers private, removed doc and moved them to satisfy dependencies * Renamed helpers to _default_ v5: * Re-introduced the helpers from v4 v4: * Fix the doc * Kill default helpers (inlined) * Fix drm_atomic_get_bridge_state() to check for an ERR_PTR() * Add Neil's R-b v3: * No changes v2: * Use drm_for_each_bridge_in_chain() * Rename helpers to be more consistent with the rest of the DRM API * Improve/fix the doc Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
2020-01-28 21:55:03 +08:00
#include <drm/drm_atomic.h>
#include <drm/drm_encoder.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_modes.h>
struct drm_bridge;
struct drm_bridge_timings;
struct drm_panel;
/**
* struct drm_bridge_funcs - drm_bridge control functions
*/
struct drm_bridge_funcs {
/**
* @attach:
*
* This callback is invoked whenever our bridge is being attached to a
* &drm_encoder.
*
* The @attach callback is optional.
*
* RETURNS:
*
* Zero on success, error code on failure.
*/
int (*attach)(struct drm_bridge *bridge);
/**
* @detach:
*
* This callback is invoked whenever our bridge is being detached from a
* &drm_encoder.
*
* The @detach callback is optional.
*/
void (*detach)(struct drm_bridge *bridge);
drm: Add crtc/encoder/bridge->mode_valid() callbacks This adds a new callback to crtc, encoder and bridge helper functions called mode_valid(). This callback shall be implemented if the corresponding component has some sort of restriction in the modes that can be displayed. A NULL callback implicates that the component can display all the modes. We also change the documentation so that the new and old callbacks are correctly documented. Only the callbacks were implemented to simplify review process, following patches will make use of them. Changes in v2 from Daniel: - Update the warning about how modes aren't filtered in atomic_check - the heleprs help out a lot more now. - Consistenly roll out that warning, crtc/encoder's atomic_check missed it. - Sprinkle more links all over the place, so it's easier to see where this stuff is used and how the differen hooks are related. - Note that ->mode_valid is optional everywhere. - Explain why the connector's mode_valid is special and does _not_ get called in atomic_check. v3: Document what can and cannot be checked in mode_valid a bit better (Andrjez). Answer: Only allowed to look at the mode, nothing else. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: Jose Abreu <joabreu@synopsys.com> Cc: Carlos Palminha <palminha@synopsys.com> Cc: Alexey Brodkin <abrodkin@synopsys.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@linux.ie> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2) Reviewed-by: Jose Abreu <joabreu@synopsys.com> (v2) Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170515093347.31098-1-daniel.vetter@ffwll.ch
2017-05-15 17:33:47 +08:00
/**
* @mode_valid:
*
* This callback is used to check if a specific mode is valid in this
* bridge. This should be implemented if the bridge has some sort of
* restriction in the modes it can display. For example, a given bridge
* may be responsible to set a clock value. If the clock can not
* produce all the values for the available modes then this callback
* can be used to restrict the number of modes to only the ones that
* can be displayed.
*
* This hook is used by the probe helpers to filter the mode list in
* drm_helper_probe_single_connector_modes(), and it is used by the
* atomic helpers to validate modes supplied by userspace in
* drm_atomic_helper_check_modeset().
*
* The @mode_valid callback is optional.
drm: Add crtc/encoder/bridge->mode_valid() callbacks This adds a new callback to crtc, encoder and bridge helper functions called mode_valid(). This callback shall be implemented if the corresponding component has some sort of restriction in the modes that can be displayed. A NULL callback implicates that the component can display all the modes. We also change the documentation so that the new and old callbacks are correctly documented. Only the callbacks were implemented to simplify review process, following patches will make use of them. Changes in v2 from Daniel: - Update the warning about how modes aren't filtered in atomic_check - the heleprs help out a lot more now. - Consistenly roll out that warning, crtc/encoder's atomic_check missed it. - Sprinkle more links all over the place, so it's easier to see where this stuff is used and how the differen hooks are related. - Note that ->mode_valid is optional everywhere. - Explain why the connector's mode_valid is special and does _not_ get called in atomic_check. v3: Document what can and cannot be checked in mode_valid a bit better (Andrjez). Answer: Only allowed to look at the mode, nothing else. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: Jose Abreu <joabreu@synopsys.com> Cc: Carlos Palminha <palminha@synopsys.com> Cc: Alexey Brodkin <abrodkin@synopsys.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@linux.ie> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2) Reviewed-by: Jose Abreu <joabreu@synopsys.com> (v2) Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170515093347.31098-1-daniel.vetter@ffwll.ch
2017-05-15 17:33:47 +08:00
*
* NOTE:
*
* Since this function is both called from the check phase of an atomic
* commit, and the mode validation in the probe paths it is not allowed
* to look at anything else but the passed-in mode, and validate it
* against configuration-invariant hardward constraints. Any further
* limits which depend upon the configuration can only be checked in
* @mode_fixup.
*
* RETURNS:
*
* drm_mode_status Enum
*/
enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge,
drm: Add crtc/encoder/bridge->mode_valid() callbacks This adds a new callback to crtc, encoder and bridge helper functions called mode_valid(). This callback shall be implemented if the corresponding component has some sort of restriction in the modes that can be displayed. A NULL callback implicates that the component can display all the modes. We also change the documentation so that the new and old callbacks are correctly documented. Only the callbacks were implemented to simplify review process, following patches will make use of them. Changes in v2 from Daniel: - Update the warning about how modes aren't filtered in atomic_check - the heleprs help out a lot more now. - Consistenly roll out that warning, crtc/encoder's atomic_check missed it. - Sprinkle more links all over the place, so it's easier to see where this stuff is used and how the differen hooks are related. - Note that ->mode_valid is optional everywhere. - Explain why the connector's mode_valid is special and does _not_ get called in atomic_check. v3: Document what can and cannot be checked in mode_valid a bit better (Andrjez). Answer: Only allowed to look at the mode, nothing else. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: Jose Abreu <joabreu@synopsys.com> Cc: Carlos Palminha <palminha@synopsys.com> Cc: Alexey Brodkin <abrodkin@synopsys.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@linux.ie> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2) Reviewed-by: Jose Abreu <joabreu@synopsys.com> (v2) Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170515093347.31098-1-daniel.vetter@ffwll.ch
2017-05-15 17:33:47 +08:00
const struct drm_display_mode *mode);
/**
* @mode_fixup:
*
* This callback is used to validate and adjust a mode. The parameter
* mode is the display mode that should be fed to the next element in
* the display chain, either the final &drm_connector or the next
* &drm_bridge. The parameter adjusted_mode is the input mode the bridge
* requires. It can be modified by this callback and does not need to
* match mode. See also &drm_crtc_state.adjusted_mode for more details.
*
* This is the only hook that allows a bridge to reject a modeset. If
* this function passes all other callbacks must succeed for this
* configuration.
*
* The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup()
* is not called when &drm_bridge_funcs.atomic_check() is implemented,
* so only one of them should be provided.
*
* NOTE:
*
* This function is called in the check phase of atomic modesets, which
* can be aborted for any reason (including on userspace's request to
* just check whether a configuration would be possible). Drivers MUST
* NOT touch any persistent state (hardware or software) or data
* structures except the passed in @state parameter.
*
drm: Add crtc/encoder/bridge->mode_valid() callbacks This adds a new callback to crtc, encoder and bridge helper functions called mode_valid(). This callback shall be implemented if the corresponding component has some sort of restriction in the modes that can be displayed. A NULL callback implicates that the component can display all the modes. We also change the documentation so that the new and old callbacks are correctly documented. Only the callbacks were implemented to simplify review process, following patches will make use of them. Changes in v2 from Daniel: - Update the warning about how modes aren't filtered in atomic_check - the heleprs help out a lot more now. - Consistenly roll out that warning, crtc/encoder's atomic_check missed it. - Sprinkle more links all over the place, so it's easier to see where this stuff is used and how the differen hooks are related. - Note that ->mode_valid is optional everywhere. - Explain why the connector's mode_valid is special and does _not_ get called in atomic_check. v3: Document what can and cannot be checked in mode_valid a bit better (Andrjez). Answer: Only allowed to look at the mode, nothing else. Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: Jose Abreu <joabreu@synopsys.com> Cc: Carlos Palminha <palminha@synopsys.com> Cc: Alexey Brodkin <abrodkin@synopsys.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Dave Airlie <airlied@linux.ie> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Archit Taneja <architt@codeaurora.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2) Reviewed-by: Jose Abreu <joabreu@synopsys.com> (v2) Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170515093347.31098-1-daniel.vetter@ffwll.ch
2017-05-15 17:33:47 +08:00
* Also beware that userspace can request its own custom modes, neither
* core nor helpers filter modes to the list of probe modes reported by
* the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
* that modes are filtered consistently put any bridge constraints and
* limits checks into @mode_valid.
*
* RETURNS:
*
* True if an acceptable configuration is possible, false if the modeset
* operation should be rejected.
*/
bool (*mode_fixup)(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
/**
* @disable:
*
* This callback should disable the bridge. It is called right before
* the preceding element in the display pipe is disabled. If the
* preceding element is a bridge this means it's called before that
* bridge's @disable vfunc. If the preceding element is a &drm_encoder
* it's called right before the &drm_encoder_helper_funcs.disable,
* &drm_encoder_helper_funcs.prepare or &drm_encoder_helper_funcs.dpms
* hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is still running when this callback is called.
*
* The @disable callback is optional.
*/
void (*disable)(struct drm_bridge *bridge);
/**
* @post_disable:
*
* This callback should disable the bridge. It is called right after the
* preceding element in the display pipe is disabled. If the preceding
* element is a bridge this means it's called after that bridge's
* @post_disable function. If the preceding element is a &drm_encoder
* it's called right after the encoder's
* &drm_encoder_helper_funcs.disable, &drm_encoder_helper_funcs.prepare
* or &drm_encoder_helper_funcs.dpms hook.
*
* The bridge must assume that the display pipe (i.e. clocks and timing
* singals) feeding it is no longer running when this callback is
* called.
*
* The @post_disable callback is optional.
*/
void (*post_disable)(struct drm_bridge *bridge);
/**
* @mode_set:
*
* This callback should set the given mode on the bridge. It is called
* after the @mode_set callback for the preceding element in the display
* pipeline has been called already. If the bridge is the first element
* then this would be &drm_encoder_helper_funcs.mode_set. The display
* pipe (i.e. clocks and timing signals) is off when this function is
* called.
*
* The adjusted_mode parameter is the mode output by the CRTC for the
* first bridge in the chain. It can be different from the mode
* parameter that contains the desired mode for the connector at the end
* of the bridges chain, for instance when the first bridge in the chain
* performs scaling. The adjusted mode is mostly useful for the first
* bridge in the chain and is likely irrelevant for the other bridges.
*
* For atomic drivers the adjusted_mode is the mode stored in
* &drm_crtc_state.adjusted_mode.
*
* NOTE:
*
* If a need arises to store and access modes adjusted for other
* locations than the connection between the CRTC and the first bridge,
* the DRM framework will have to be extended with DRM bridge states.
*/
void (*mode_set)(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode);
/**
* @pre_enable:
*
* This callback should enable the bridge. It is called right before
* the preceding element in the display pipe is enabled. If the
* preceding element is a bridge this means it's called before that
* bridge's @pre_enable function. If the preceding element is a
* &drm_encoder it's called right before the encoder's
* &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
* &drm_encoder_helper_funcs.dpms hook.
*
* The display pipe (i.e. clocks and timing signals) feeding this bridge
* will not yet be running when this callback is called. The bridge must
* not enable the display link feeding the next bridge in the chain (if
* there is one) when this callback is called.
*
* The @pre_enable callback is optional.
*/
void (*pre_enable)(struct drm_bridge *bridge);
/**
* @enable:
*
* This callback should enable the bridge. It is called right after
* the preceding element in the display pipe is enabled. If the
* preceding element is a bridge this means it's called after that
* bridge's @enable function. If the preceding element is a
* &drm_encoder it's called right after the encoder's
* &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
* &drm_encoder_helper_funcs.dpms hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is running when this callback is called. This
* callback must enable the display link feeding the next bridge in the
* chain if there is one.
*
* The @enable callback is optional.
*/
void (*enable)(struct drm_bridge *bridge);
/**
* @atomic_pre_enable:
*
* This callback should enable the bridge. It is called right before
* the preceding element in the display pipe is enabled. If the
* preceding element is a bridge this means it's called before that
* bridge's @atomic_pre_enable or @pre_enable function. If the preceding
* element is a &drm_encoder it's called right before the encoder's
* &drm_encoder_helper_funcs.atomic_enable hook.
*
* The display pipe (i.e. clocks and timing signals) feeding this bridge
* will not yet be running when this callback is called. The bridge must
* not enable the display link feeding the next bridge in the chain (if
* there is one) when this callback is called.
*
* Note that this function will only be invoked in the context of an
* atomic commit. It will not be invoked from
* &drm_bridge_chain_pre_enable. It would be prudent to also provide an
* implementation of @pre_enable if you are expecting driver calls into
* &drm_bridge_chain_pre_enable.
*
* The @atomic_pre_enable callback is optional.
*/
void (*atomic_pre_enable)(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state);
/**
* @atomic_enable:
*
* This callback should enable the bridge. It is called right after
* the preceding element in the display pipe is enabled. If the
* preceding element is a bridge this means it's called after that
* bridge's @atomic_enable or @enable function. If the preceding element
* is a &drm_encoder it's called right after the encoder's
* &drm_encoder_helper_funcs.atomic_enable hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is running when this callback is called. This
* callback must enable the display link feeding the next bridge in the
* chain if there is one.
*
* Note that this function will only be invoked in the context of an
* atomic commit. It will not be invoked from &drm_bridge_chain_enable.
* It would be prudent to also provide an implementation of @enable if
* you are expecting driver calls into &drm_bridge_chain_enable.
*
* The @atomic_enable callback is optional.
*/
void (*atomic_enable)(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state);
/**
* @atomic_disable:
*
* This callback should disable the bridge. It is called right before
* the preceding element in the display pipe is disabled. If the
* preceding element is a bridge this means it's called before that
* bridge's @atomic_disable or @disable vfunc. If the preceding element
* is a &drm_encoder it's called right before the
* &drm_encoder_helper_funcs.atomic_disable hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is still running when this callback is called.
*
* Note that this function will only be invoked in the context of an
* atomic commit. It will not be invoked from
* &drm_bridge_chain_disable. It would be prudent to also provide an
* implementation of @disable if you are expecting driver calls into
* &drm_bridge_chain_disable.
*
* The @atomic_disable callback is optional.
*/
void (*atomic_disable)(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state);
/**
* @atomic_post_disable:
*
* This callback should disable the bridge. It is called right after the
* preceding element in the display pipe is disabled. If the preceding
* element is a bridge this means it's called after that bridge's
* @atomic_post_disable or @post_disable function. If the preceding
* element is a &drm_encoder it's called right after the encoder's
* &drm_encoder_helper_funcs.atomic_disable hook.
*
* The bridge must assume that the display pipe (i.e. clocks and timing
* signals) feeding it is no longer running when this callback is
* called.
*
* Note that this function will only be invoked in the context of an
* atomic commit. It will not be invoked from
* &drm_bridge_chain_post_disable.
* It would be prudent to also provide an implementation of
* @post_disable if you are expecting driver calls into
* &drm_bridge_chain_post_disable.
*
* The @atomic_post_disable callback is optional.
*/
void (*atomic_post_disable)(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state);
drm/bridge: Add a drm_bridge_state object One of the last remaining objects to not have its atomic state. This is being motivated by our attempt to support runtime bus-format negotiation between elements of the bridge chain. This patch just paves the road for such a feature by adding a new drm_bridge_state object inheriting from drm_private_obj so we can re-use some of the existing state initialization/tracking logic. v10: * Add changelog to the commit message v9: * Clarify the fact that the bridge->atomic_reset() and {connector,plane,crtc,...}->reset() semantics are different * Move the drm_atomic_private_obj_init() call back to drm_bridge_attach() * Check the presence of ->atomic_duplicate_state instead of ->atomic_reset in drm_atomic_add_encoder_bridges() * Fix copy&paste errors in the atomic bridge state helpers doc * Add A-b/R-b tags v8: * Move bridge state helpers out of the CONFIG_DEBUGFS section v7: * Move helpers, struct-defs, ... to atomic helper files to avoid the drm -> drm_kms_helper -> drm circular dep * Stop providing default implementation for atomic state reset, duplicate and destroy hooks (has to do with the helper/core split) * Drop all R-b/T-b as helpers have now be moved to other places v6: * Made helpers private, removed doc and moved them to satisfy dependencies * Renamed helpers to _default_ v5: * Re-introduced the helpers from v4 v4: * Fix the doc * Kill default helpers (inlined) * Fix drm_atomic_get_bridge_state() to check for an ERR_PTR() * Add Neil's R-b v3: * No changes v2: * Use drm_for_each_bridge_in_chain() * Rename helpers to be more consistent with the rest of the DRM API * Improve/fix the doc Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
2020-01-28 21:55:03 +08:00
/**
* @atomic_duplicate_state:
*
* Duplicate the current bridge state object (which is guaranteed to be
* non-NULL).
*
* The atomic_duplicate_state() is optional. When not implemented the
* core allocates a drm_bridge_state object and calls
* &__drm_atomic_helper_bridge_duplicate_state() to initialize it.
*
* RETURNS:
* A valid drm_bridge_state object or NULL if the allocation fails.
*/
struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge);
/**
* @atomic_destroy_state:
*
* Destroy a bridge state object previously allocated by
* &drm_bridge_funcs.atomic_duplicate_state().
*
* The atomic_destroy_state hook is optional. When not implemented the
* core calls kfree() on the state.
*/
void (*atomic_destroy_state)(struct drm_bridge *bridge,
struct drm_bridge_state *state);
drm/bridge: Add the necessary bits to support bus format negotiation drm_bridge_state is extended to describe the input and output bus configurations. These bus configurations are exposed through the drm_bus_cfg struct which encodes the configuration of a physical bus between two components in an output pipeline, usually between two bridges, an encoder and a bridge, or a bridge and a connector. The bus configuration is stored in drm_bridge_state separately for the input and output buses, as seen from the point of view of each bridge. The bus configuration of a bridge output is usually identical to the configuration of the next bridge's input, but may differ if the signals are modified between the two bridges, for instance by an inverter on the board. The input and output configurations of a bridge may differ if the bridge modifies the signals internally, for instance by performing format conversion, or*modifying signals polarities. Bus format negotiation is automated by the core, drivers just have to implement the ->atomic_get_{output,input}_bus_fmts() hooks if they want to take part to this negotiation. Negotiation happens in reverse order, starting from the last element of the chain (the one directly connected to the display) up to the first element of the chain (the one connected to the encoder). During this negotiation all supported formats are tested until we find one that works, meaning that the formats array should be in decreasing preference order (assuming the driver has a preference order). Note that the bus format negotiation works even if some elements in the chain don't implement the ->atomic_get_{output,input}_bus_fmts() hooks. In that case, the core advertises only MEDIA_BUS_FMT_FIXED and lets the previous bridge element decide what to do (most of the time, bridge drivers will pick a default bus format or extract this piece of information from somewhere else, like a FW property). v10: * Add changelog to the commit message v9: * No changes v8: * Fix a test in drm_atomic_bridge_chain_select_bus_fmts() (Reported by Jonas) v7: * Adapt the code to deal with the fact that not all bridges in the chain have a bridge state v5 -> v6: * No changes v4: * Enhance the doc * Fix typos * Rename some parameters/fields * Reword the commit message v3: * Fix the commit message (Reported by Laurent) * Document the fact that bus formats should not be directly modified by drivers (Suggested by Laurent) * Document the fact that format order matters (Suggested by Laurent) * Propagate bus flags by default * Document the fact that drivers can tweak bus flags if needed * Let ->atomic_get_{output,input}_bus_fmts() allocate the bus format array (Suggested by Laurent) * Add a drm_atomic_helper_bridge_propagate_bus_fmt() * Mandate that bridge drivers return accurate input_fmts even if they are known to be the first element in the bridge chain v2: * Rework things to support more complex use cases Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> [narmstrong: fixed doc in include/drm/drm_bridge.h:69 fmt->format] Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net> Tested-by: Jonas Karlman <jonas@kwiboo.se> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-7-boris.brezillon@collabora.com
2020-01-28 21:55:08 +08:00
/**
* @atomic_get_output_bus_fmts:
*
* Return the supported bus formats on the output end of a bridge.
* The returned array must be allocated with kmalloc() and will be
* freed by the caller. If the allocation fails, NULL should be
* returned. num_output_fmts must be set to the returned array size.
* Formats listed in the returned array should be listed in decreasing
* preference order (the core will try all formats until it finds one
* that works).
*
* This method is only called on the last element of the bridge chain
* as part of the bus format negotiation process that happens in
* &drm_atomic_bridge_chain_select_bus_fmts().
* This method is optional. When not implemented, the core will
* fall back to &drm_connector.display_info.bus_formats[0] if
* &drm_connector.display_info.num_bus_formats > 0,
* or to MEDIA_BUS_FMT_FIXED otherwise.
*/
u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
unsigned int *num_output_fmts);
/**
* @atomic_get_input_bus_fmts:
*
* Return the supported bus formats on the input end of a bridge for
* a specific output bus format.
*
* The returned array must be allocated with kmalloc() and will be
* freed by the caller. If the allocation fails, NULL should be
* returned. num_output_fmts must be set to the returned array size.
* Formats listed in the returned array should be listed in decreasing
* preference order (the core will try all formats until it finds one
* that works). When the format is not supported NULL should be
* returned and *num_output_fmts should be set to 0.
*
* This method is called on all elements of the bridge chain as part of
* the bus format negotiation process that happens in
* &drm_atomic_bridge_chain_select_bus_fmts().
* This method is optional. When not implemented, the core will bypass
* bus format negotiation on this element of the bridge without
* failing, and the previous element in the chain will be passed
* MEDIA_BUS_FMT_FIXED as its output bus format.
*
* Bridge drivers that need to support being linked to bridges that are
* not supporting bus format negotiation should handle the
* output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a
* sensible default value or extracting this information from somewhere
* else (FW property, &drm_display_mode, &drm_display_info, ...)
*
* Note: Even if input format selection on the first bridge has no
* impact on the negotiation process (bus format negotiation stops once
* we reach the first element of the chain), drivers are expected to
* return accurate input formats as the input format may be used to
* configure the CRTC output appropriately.
*/
u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
u32 output_fmt,
unsigned int *num_input_fmts);
/**
* @atomic_check:
*
* This method is responsible for checking bridge state correctness.
* It can also check the state of the surrounding components in chain
* to make sure the whole pipeline can work properly.
*
* &drm_bridge_funcs.atomic_check() hooks are called in reverse
* order (from the last to the first bridge).
*
* This method is optional. &drm_bridge_funcs.mode_fixup() is not
* called when &drm_bridge_funcs.atomic_check() is implemented, so only
* one of them should be provided.
*
drm/bridge: Add the necessary bits to support bus format negotiation drm_bridge_state is extended to describe the input and output bus configurations. These bus configurations are exposed through the drm_bus_cfg struct which encodes the configuration of a physical bus between two components in an output pipeline, usually between two bridges, an encoder and a bridge, or a bridge and a connector. The bus configuration is stored in drm_bridge_state separately for the input and output buses, as seen from the point of view of each bridge. The bus configuration of a bridge output is usually identical to the configuration of the next bridge's input, but may differ if the signals are modified between the two bridges, for instance by an inverter on the board. The input and output configurations of a bridge may differ if the bridge modifies the signals internally, for instance by performing format conversion, or*modifying signals polarities. Bus format negotiation is automated by the core, drivers just have to implement the ->atomic_get_{output,input}_bus_fmts() hooks if they want to take part to this negotiation. Negotiation happens in reverse order, starting from the last element of the chain (the one directly connected to the display) up to the first element of the chain (the one connected to the encoder). During this negotiation all supported formats are tested until we find one that works, meaning that the formats array should be in decreasing preference order (assuming the driver has a preference order). Note that the bus format negotiation works even if some elements in the chain don't implement the ->atomic_get_{output,input}_bus_fmts() hooks. In that case, the core advertises only MEDIA_BUS_FMT_FIXED and lets the previous bridge element decide what to do (most of the time, bridge drivers will pick a default bus format or extract this piece of information from somewhere else, like a FW property). v10: * Add changelog to the commit message v9: * No changes v8: * Fix a test in drm_atomic_bridge_chain_select_bus_fmts() (Reported by Jonas) v7: * Adapt the code to deal with the fact that not all bridges in the chain have a bridge state v5 -> v6: * No changes v4: * Enhance the doc * Fix typos * Rename some parameters/fields * Reword the commit message v3: * Fix the commit message (Reported by Laurent) * Document the fact that bus formats should not be directly modified by drivers (Suggested by Laurent) * Document the fact that format order matters (Suggested by Laurent) * Propagate bus flags by default * Document the fact that drivers can tweak bus flags if needed * Let ->atomic_get_{output,input}_bus_fmts() allocate the bus format array (Suggested by Laurent) * Add a drm_atomic_helper_bridge_propagate_bus_fmt() * Mandate that bridge drivers return accurate input_fmts even if they are known to be the first element in the bridge chain v2: * Rework things to support more complex use cases Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> [narmstrong: fixed doc in include/drm/drm_bridge.h:69 fmt->format] Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net> Tested-by: Jonas Karlman <jonas@kwiboo.se> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-7-boris.brezillon@collabora.com
2020-01-28 21:55:08 +08:00
* If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or
* &drm_bridge_state.output_bus_cfg.flags it should should happen in
* this function. By default the &drm_bridge_state.output_bus_cfg.flags
* field is set to the next bridge
* &drm_bridge_state.input_bus_cfg.flags value or
* &drm_connector.display_info.bus_flags if the bridge is the last
* element in the chain.
*
* RETURNS:
* zero if the check passed, a negative error code otherwise.
*/
int (*atomic_check)(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state);
drm/bridge: Add a drm_bridge_state object One of the last remaining objects to not have its atomic state. This is being motivated by our attempt to support runtime bus-format negotiation between elements of the bridge chain. This patch just paves the road for such a feature by adding a new drm_bridge_state object inheriting from drm_private_obj so we can re-use some of the existing state initialization/tracking logic. v10: * Add changelog to the commit message v9: * Clarify the fact that the bridge->atomic_reset() and {connector,plane,crtc,...}->reset() semantics are different * Move the drm_atomic_private_obj_init() call back to drm_bridge_attach() * Check the presence of ->atomic_duplicate_state instead of ->atomic_reset in drm_atomic_add_encoder_bridges() * Fix copy&paste errors in the atomic bridge state helpers doc * Add A-b/R-b tags v8: * Move bridge state helpers out of the CONFIG_DEBUGFS section v7: * Move helpers, struct-defs, ... to atomic helper files to avoid the drm -> drm_kms_helper -> drm circular dep * Stop providing default implementation for atomic state reset, duplicate and destroy hooks (has to do with the helper/core split) * Drop all R-b/T-b as helpers have now be moved to other places v6: * Made helpers private, removed doc and moved them to satisfy dependencies * Renamed helpers to _default_ v5: * Re-introduced the helpers from v4 v4: * Fix the doc * Kill default helpers (inlined) * Fix drm_atomic_get_bridge_state() to check for an ERR_PTR() * Add Neil's R-b v3: * No changes v2: * Use drm_for_each_bridge_in_chain() * Rename helpers to be more consistent with the rest of the DRM API * Improve/fix the doc Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
2020-01-28 21:55:03 +08:00
/**
* @atomic_reset:
*
* Reset the bridge to a predefined state (or retrieve its current
* state) and return a &drm_bridge_state object matching this state.
* This function is called at attach time.
*
* The atomic_reset hook is mandatory if the bridge implements any of
* the atomic hooks, and should be left unassigned otherwise.
*
* Note that the atomic_reset() semantics is not exactly matching the
* reset() semantics found on other components (connector, plane, ...).
* 1/ The reset operation happens when the bridge is attached, not when
* drm_mode_config_reset() is called
* 2/ It's meant to be used exclusively on bridges that have been
* converted to the ATOMIC API
*
* RETURNS:
* A valid drm_bridge_state object in case of success, an ERR_PTR()
* giving the reason of the failure otherwise.
*/
struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge);
};
/**
* struct drm_bridge_timings - timing information for the bridge
*/
struct drm_bridge_timings {
/**
* @input_bus_flags:
*
* Tells what additional settings for the pixel data on the bus
* this bridge requires (like pixel signal polarity). See also
* &drm_display_info->bus_flags.
*/
u32 input_bus_flags;
/**
* @setup_time_ps:
*
* Defines the time in picoseconds the input data lines must be
* stable before the clock edge.
*/
u32 setup_time_ps;
/**
* @hold_time_ps:
*
* Defines the time in picoseconds taken for the bridge to sample the
* input signal after the clock edge.
*/
u32 hold_time_ps;
/**
* @dual_link:
*
* True if the bus operates in dual-link mode. The exact meaning is
* dependent on the bus type. For LVDS buses, this indicates that even-
* and odd-numbered pixels are received on separate links.
*/
bool dual_link;
};
/**
* struct drm_bridge - central DRM bridge control structure
*/
struct drm_bridge {
drm/bridge: Add a drm_bridge_state object One of the last remaining objects to not have its atomic state. This is being motivated by our attempt to support runtime bus-format negotiation between elements of the bridge chain. This patch just paves the road for such a feature by adding a new drm_bridge_state object inheriting from drm_private_obj so we can re-use some of the existing state initialization/tracking logic. v10: * Add changelog to the commit message v9: * Clarify the fact that the bridge->atomic_reset() and {connector,plane,crtc,...}->reset() semantics are different * Move the drm_atomic_private_obj_init() call back to drm_bridge_attach() * Check the presence of ->atomic_duplicate_state instead of ->atomic_reset in drm_atomic_add_encoder_bridges() * Fix copy&paste errors in the atomic bridge state helpers doc * Add A-b/R-b tags v8: * Move bridge state helpers out of the CONFIG_DEBUGFS section v7: * Move helpers, struct-defs, ... to atomic helper files to avoid the drm -> drm_kms_helper -> drm circular dep * Stop providing default implementation for atomic state reset, duplicate and destroy hooks (has to do with the helper/core split) * Drop all R-b/T-b as helpers have now be moved to other places v6: * Made helpers private, removed doc and moved them to satisfy dependencies * Renamed helpers to _default_ v5: * Re-introduced the helpers from v4 v4: * Fix the doc * Kill default helpers (inlined) * Fix drm_atomic_get_bridge_state() to check for an ERR_PTR() * Add Neil's R-b v3: * No changes v2: * Use drm_for_each_bridge_in_chain() * Rename helpers to be more consistent with the rest of the DRM API * Improve/fix the doc Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
2020-01-28 21:55:03 +08:00
/** @base: inherit from &drm_private_object */
struct drm_private_obj base;
/** @dev: DRM device this bridge belongs to */
struct drm_device *dev;
/** @encoder: encoder to which this bridge is connected */
struct drm_encoder *encoder;
/** @chain_node: used to form a bridge chain */
struct list_head chain_node;
#ifdef CONFIG_OF
/** @of_node: device node pointer to the bridge */
struct device_node *of_node;
#endif
/** @list: to keep track of all added bridges */
struct list_head list;
/**
* @timings:
*
* the timing specification for the bridge, if any (may be NULL)
*/
const struct drm_bridge_timings *timings;
/** @funcs: control functions */
const struct drm_bridge_funcs *funcs;
/** @driver_private: pointer to the bridge driver's internal context */
void *driver_private;
};
drm/bridge: Add a drm_bridge_state object One of the last remaining objects to not have its atomic state. This is being motivated by our attempt to support runtime bus-format negotiation between elements of the bridge chain. This patch just paves the road for such a feature by adding a new drm_bridge_state object inheriting from drm_private_obj so we can re-use some of the existing state initialization/tracking logic. v10: * Add changelog to the commit message v9: * Clarify the fact that the bridge->atomic_reset() and {connector,plane,crtc,...}->reset() semantics are different * Move the drm_atomic_private_obj_init() call back to drm_bridge_attach() * Check the presence of ->atomic_duplicate_state instead of ->atomic_reset in drm_atomic_add_encoder_bridges() * Fix copy&paste errors in the atomic bridge state helpers doc * Add A-b/R-b tags v8: * Move bridge state helpers out of the CONFIG_DEBUGFS section v7: * Move helpers, struct-defs, ... to atomic helper files to avoid the drm -> drm_kms_helper -> drm circular dep * Stop providing default implementation for atomic state reset, duplicate and destroy hooks (has to do with the helper/core split) * Drop all R-b/T-b as helpers have now be moved to other places v6: * Made helpers private, removed doc and moved them to satisfy dependencies * Renamed helpers to _default_ v5: * Re-introduced the helpers from v4 v4: * Fix the doc * Kill default helpers (inlined) * Fix drm_atomic_get_bridge_state() to check for an ERR_PTR() * Add Neil's R-b v3: * No changes v2: * Use drm_for_each_bridge_in_chain() * Rename helpers to be more consistent with the rest of the DRM API * Improve/fix the doc Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-2-boris.brezillon@collabora.com
2020-01-28 21:55:03 +08:00
static inline struct drm_bridge *
drm_priv_to_bridge(struct drm_private_obj *priv)
{
return container_of(priv, struct drm_bridge, base);
}
void drm_bridge_add(struct drm_bridge *bridge);
void drm_bridge_remove(struct drm_bridge *bridge);
struct drm_bridge *of_drm_find_bridge(struct device_node *np);
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
struct drm_bridge *previous);
/**
* drm_bridge_get_next_bridge() - Get the next bridge in the chain
* @bridge: bridge object
*
* RETURNS:
* the next bridge in the chain after @bridge, or NULL if @bridge is the last.
*/
static inline struct drm_bridge *
drm_bridge_get_next_bridge(struct drm_bridge *bridge)
{
if (list_is_last(&bridge->chain_node, &bridge->encoder->bridge_chain))
return NULL;
return list_next_entry(bridge, chain_node);
}
/**
* drm_bridge_get_prev_bridge() - Get the previous bridge in the chain
* @bridge: bridge object
*
* RETURNS:
* the previous bridge in the chain, or NULL if @bridge is the first.
*/
static inline struct drm_bridge *
drm_bridge_get_prev_bridge(struct drm_bridge *bridge)
{
if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
return NULL;
return list_prev_entry(bridge, chain_node);
}
/**
* drm_bridge_chain_get_first_bridge() - Get the first bridge in the chain
* @encoder: encoder object
*
* RETURNS:
* the first bridge in the chain, or NULL if @encoder has no bridge attached
* to it.
*/
static inline struct drm_bridge *
drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
{
return list_first_entry_or_null(&encoder->bridge_chain,
struct drm_bridge, chain_node);
}
/**
* drm_for_each_bridge_in_chain() - Iterate over all bridges present in a chain
* @encoder: the encoder to iterate bridges on
* @bridge: a bridge pointer updated to point to the current bridge at each
* iteration
*
* Iterate over all bridges present in the bridge chain attached to @encoder.
*/
#define drm_for_each_bridge_in_chain(encoder, bridge) \
list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node)
bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_mode *mode);
void drm_bridge_chain_disable(struct drm_bridge *bridge);
void drm_bridge_chain_post_disable(struct drm_bridge *bridge);
void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode);
void drm_bridge_chain_pre_enable(struct drm_bridge *bridge);
void drm_bridge_chain_enable(struct drm_bridge *bridge);
int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state);
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
drm/bridge: Add the necessary bits to support bus format negotiation drm_bridge_state is extended to describe the input and output bus configurations. These bus configurations are exposed through the drm_bus_cfg struct which encodes the configuration of a physical bus between two components in an output pipeline, usually between two bridges, an encoder and a bridge, or a bridge and a connector. The bus configuration is stored in drm_bridge_state separately for the input and output buses, as seen from the point of view of each bridge. The bus configuration of a bridge output is usually identical to the configuration of the next bridge's input, but may differ if the signals are modified between the two bridges, for instance by an inverter on the board. The input and output configurations of a bridge may differ if the bridge modifies the signals internally, for instance by performing format conversion, or*modifying signals polarities. Bus format negotiation is automated by the core, drivers just have to implement the ->atomic_get_{output,input}_bus_fmts() hooks if they want to take part to this negotiation. Negotiation happens in reverse order, starting from the last element of the chain (the one directly connected to the display) up to the first element of the chain (the one connected to the encoder). During this negotiation all supported formats are tested until we find one that works, meaning that the formats array should be in decreasing preference order (assuming the driver has a preference order). Note that the bus format negotiation works even if some elements in the chain don't implement the ->atomic_get_{output,input}_bus_fmts() hooks. In that case, the core advertises only MEDIA_BUS_FMT_FIXED and lets the previous bridge element decide what to do (most of the time, bridge drivers will pick a default bus format or extract this piece of information from somewhere else, like a FW property). v10: * Add changelog to the commit message v9: * No changes v8: * Fix a test in drm_atomic_bridge_chain_select_bus_fmts() (Reported by Jonas) v7: * Adapt the code to deal with the fact that not all bridges in the chain have a bridge state v5 -> v6: * No changes v4: * Enhance the doc * Fix typos * Rename some parameters/fields * Reword the commit message v3: * Fix the commit message (Reported by Laurent) * Document the fact that bus formats should not be directly modified by drivers (Suggested by Laurent) * Document the fact that format order matters (Suggested by Laurent) * Propagate bus flags by default * Document the fact that drivers can tweak bus flags if needed * Let ->atomic_get_{output,input}_bus_fmts() allocate the bus format array (Suggested by Laurent) * Add a drm_atomic_helper_bridge_propagate_bus_fmt() * Mandate that bridge drivers return accurate input_fmts even if they are known to be the first element in the bridge chain v2: * Rework things to support more complex use cases Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> [narmstrong: fixed doc in include/drm/drm_bridge.h:69 fmt->format] Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net> Tested-by: Jonas Karlman <jonas@kwiboo.se> Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-7-boris.brezillon@collabora.com
2020-01-28 21:55:08 +08:00
u32 *
drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
u32 output_fmt,
unsigned int *num_input_fmts);
#ifdef CONFIG_DRM_PANEL_BRIDGE
drm/bridge: panel: Infer connector type from panel by default The drm panel bridge creates a connector using a connector type explicitly passed by the display controller or bridge driver that instantiates the panel bridge. Now that drm_panel reports its connector type, we can use it to avoid passing an explicit (and often incorrect) connector type to drm_panel_bridge_add() and devm_drm_panel_bridge_add(). Several drivers report incorrect or unknown connector types to userspace. Reporting a different type may result in a breakage. For that reason, rename (devm_)drm_panel_bridge_add() to (devm_)drm_panel_bridge_add_typed(), and add new (devm_)drm_panel_bridge_add() functions that use the panel connector type. Update all callers of (devm_)drm_panel_bridge_add() to the _typed function, they will be converted one by one after testing. The panel drivers have been updated with the following Coccinelle semantic patch, with manual inspection and fixes to indentation. @@ expression bridge; expression dev; expression panel; identifier type; @@ ( -bridge = drm_panel_bridge_add(panel, type); +bridge = drm_panel_bridge_add_typed(panel, type); | -bridge = devm_drm_panel_bridge_add(dev, panel, type); +bridge = devm_drm_panel_bridge_add_typed(dev, panel, type); ) Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190904132804.29680-3-laurent.pinchart@ideasonboard.com
2019-09-04 21:28:04 +08:00
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
u32 connector_type);
void drm_panel_bridge_remove(struct drm_bridge *bridge);
struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
drm/bridge: panel: Infer connector type from panel by default The drm panel bridge creates a connector using a connector type explicitly passed by the display controller or bridge driver that instantiates the panel bridge. Now that drm_panel reports its connector type, we can use it to avoid passing an explicit (and often incorrect) connector type to drm_panel_bridge_add() and devm_drm_panel_bridge_add(). Several drivers report incorrect or unknown connector types to userspace. Reporting a different type may result in a breakage. For that reason, rename (devm_)drm_panel_bridge_add() to (devm_)drm_panel_bridge_add_typed(), and add new (devm_)drm_panel_bridge_add() functions that use the panel connector type. Update all callers of (devm_)drm_panel_bridge_add() to the _typed function, they will be converted one by one after testing. The panel drivers have been updated with the following Coccinelle semantic patch, with manual inspection and fixes to indentation. @@ expression bridge; expression dev; expression panel; identifier type; @@ ( -bridge = drm_panel_bridge_add(panel, type); +bridge = drm_panel_bridge_add_typed(panel, type); | -bridge = devm_drm_panel_bridge_add(dev, panel, type); +bridge = devm_drm_panel_bridge_add_typed(dev, panel, type); ) Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190904132804.29680-3-laurent.pinchart@ideasonboard.com
2019-09-04 21:28:04 +08:00
struct drm_panel *panel);
struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
struct drm_panel *panel,
u32 connector_type);
struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
#endif
#endif