/*
* 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/cleanup.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <drm/drm_atomic.h>
#include <drm/drm_encoder.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_modes.h>
struct cec_msg;
struct device_node;
struct drm_bridge;
struct drm_bridge_timings;
struct drm_connector;
struct drm_display_info;
struct drm_minor;
struct drm_panel;
struct edid;
struct hdmi_codec_daifmt;
struct hdmi_codec_params;
struct i2c_adapter;
/**
* enum drm_bridge_attach_flags - Flags for &drm_bridge_funcs.attach
*/
enum drm_bridge_attach_flags {
/**
* @DRM_BRIDGE_ATTACH_NO_CONNECTOR: When this flag is set the bridge
* shall not create a drm_connector.
*/
DRM_BRIDGE_ATTACH_NO_CONNECTOR = BIT(0),
};
/**
* 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 flags argument tunes the behaviour of the attach
* operation (see DRM_BRIDGE_ATTACH_*).
*
* The @attach callback is optional.
*
* RETURNS:
*
* Zero on success, error code on failure.
*/
int (*attach)(struct drm_bridge *bridge, struct drm_encoder *encoder,
enum drm_bridge_attach_flags flags);
/**
* @destroy:
*
* This callback is invoked when the bridge is about to be
* deallocated.
*
* The @destroy callback is optional.
*/
void (*destroy)(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);
/**
* @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.
*
* 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 hardware 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,
const struct drm_display_info *info,
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.
*
* 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:
*
* The @disable callback should disable the bridge.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is still running when this callback is called.
*
*
* If the preceding element is a &drm_bridge, then this is called before
* that bridge is disabled via one of:
*
* - &drm_bridge_funcs.disable
* - &drm_bridge_funcs.atomic_disable
*
* If the preceding element of the bridge is a display controller, then
* this callback is called before the encoder is disabled via one of:
*
* - &drm_encoder_helper_funcs.atomic_disable
* - &drm_encoder_helper_funcs.prepare
* - &drm_encoder_helper_funcs.disable
* - &drm_encoder_helper_funcs.dpms
*
* and the CRTC is disabled via one of:
*
* - &drm_crtc_helper_funcs.prepare
* - &drm_crtc_helper_funcs.atomic_disable
* - &drm_crtc_helper_funcs.disable
* - &drm_crtc_helper_funcs.dpms.
*
* The @disable callback is optional.
*
* NOTE:
*
* This is deprecated, do not use!
* New drivers shall use &drm_bridge_funcs.atomic_disable.
*/
void (*disable)(struct drm_bridge *bridge);
/**
* @post_disable:
*
* The bridge must assume that the display pipe (i.e. clocks and timing
* signals) feeding this bridge is no
|