18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2016 Intel Corporation 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, distribute, and sell this software and its 58c2ecf20Sopenharmony_ci * documentation for any purpose is hereby granted without fee, provided that 68c2ecf20Sopenharmony_ci * the above copyright notice appear in all copies and that both that copyright 78c2ecf20Sopenharmony_ci * notice and this permission notice appear in supporting documentation, and 88c2ecf20Sopenharmony_ci * that the name of the copyright holders not be used in advertising or 98c2ecf20Sopenharmony_ci * publicity pertaining to distribution of the software without specific, 108c2ecf20Sopenharmony_ci * written prior permission. The copyright holders make no representations 118c2ecf20Sopenharmony_ci * about the suitability of this software for any purpose. It is provided "as 128c2ecf20Sopenharmony_ci * is" without express or implied warranty. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 158c2ecf20Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 168c2ecf20Sopenharmony_ci * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 178c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 188c2ecf20Sopenharmony_ci * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 198c2ecf20Sopenharmony_ci * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 208c2ecf20Sopenharmony_ci * OF THIS SOFTWARE. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#ifndef __DRM_BRIDGE_H__ 248c2ecf20Sopenharmony_ci#define __DRM_BRIDGE_H__ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#include <linux/ctype.h> 278c2ecf20Sopenharmony_ci#include <linux/list.h> 288c2ecf20Sopenharmony_ci#include <linux/mutex.h> 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#include <drm/drm_atomic.h> 318c2ecf20Sopenharmony_ci#include <drm/drm_encoder.h> 328c2ecf20Sopenharmony_ci#include <drm/drm_mode_object.h> 338c2ecf20Sopenharmony_ci#include <drm/drm_modes.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistruct drm_bridge; 368c2ecf20Sopenharmony_cistruct drm_bridge_timings; 378c2ecf20Sopenharmony_cistruct drm_connector; 388c2ecf20Sopenharmony_cistruct drm_display_info; 398c2ecf20Sopenharmony_cistruct drm_panel; 408c2ecf20Sopenharmony_cistruct edid; 418c2ecf20Sopenharmony_cistruct i2c_adapter; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/** 448c2ecf20Sopenharmony_ci * enum drm_bridge_attach_flags - Flags for &drm_bridge_funcs.attach 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_cienum drm_bridge_attach_flags { 478c2ecf20Sopenharmony_ci /** 488c2ecf20Sopenharmony_ci * @DRM_BRIDGE_ATTACH_NO_CONNECTOR: When this flag is set the bridge 498c2ecf20Sopenharmony_ci * shall not create a drm_connector. 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci DRM_BRIDGE_ATTACH_NO_CONNECTOR = BIT(0), 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/** 558c2ecf20Sopenharmony_ci * struct drm_bridge_funcs - drm_bridge control functions 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_cistruct drm_bridge_funcs { 588c2ecf20Sopenharmony_ci /** 598c2ecf20Sopenharmony_ci * @attach: 608c2ecf20Sopenharmony_ci * 618c2ecf20Sopenharmony_ci * This callback is invoked whenever our bridge is being attached to a 628c2ecf20Sopenharmony_ci * &drm_encoder. The flags argument tunes the behaviour of the attach 638c2ecf20Sopenharmony_ci * operation (see DRM_BRIDGE_ATTACH_*). 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * The @attach callback is optional. 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * RETURNS: 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * Zero on success, error code on failure. 708c2ecf20Sopenharmony_ci */ 718c2ecf20Sopenharmony_ci int (*attach)(struct drm_bridge *bridge, 728c2ecf20Sopenharmony_ci enum drm_bridge_attach_flags flags); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /** 758c2ecf20Sopenharmony_ci * @detach: 768c2ecf20Sopenharmony_ci * 778c2ecf20Sopenharmony_ci * This callback is invoked whenever our bridge is being detached from a 788c2ecf20Sopenharmony_ci * &drm_encoder. 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci * The @detach callback is optional. 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_ci void (*detach)(struct drm_bridge *bridge); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /** 858c2ecf20Sopenharmony_ci * @mode_valid: 868c2ecf20Sopenharmony_ci * 878c2ecf20Sopenharmony_ci * This callback is used to check if a specific mode is valid in this 888c2ecf20Sopenharmony_ci * bridge. This should be implemented if the bridge has some sort of 898c2ecf20Sopenharmony_ci * restriction in the modes it can display. For example, a given bridge 908c2ecf20Sopenharmony_ci * may be responsible to set a clock value. If the clock can not 918c2ecf20Sopenharmony_ci * produce all the values for the available modes then this callback 928c2ecf20Sopenharmony_ci * can be used to restrict the number of modes to only the ones that 938c2ecf20Sopenharmony_ci * can be displayed. 948c2ecf20Sopenharmony_ci * 958c2ecf20Sopenharmony_ci * This hook is used by the probe helpers to filter the mode list in 968c2ecf20Sopenharmony_ci * drm_helper_probe_single_connector_modes(), and it is used by the 978c2ecf20Sopenharmony_ci * atomic helpers to validate modes supplied by userspace in 988c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(). 998c2ecf20Sopenharmony_ci * 1008c2ecf20Sopenharmony_ci * The @mode_valid callback is optional. 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * NOTE: 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * Since this function is both called from the check phase of an atomic 1058c2ecf20Sopenharmony_ci * commit, and the mode validation in the probe paths it is not allowed 1068c2ecf20Sopenharmony_ci * to look at anything else but the passed-in mode, and validate it 1078c2ecf20Sopenharmony_ci * against configuration-invariant hardward constraints. Any further 1088c2ecf20Sopenharmony_ci * limits which depend upon the configuration can only be checked in 1098c2ecf20Sopenharmony_ci * @mode_fixup. 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * RETURNS: 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * drm_mode_status Enum 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge, 1168c2ecf20Sopenharmony_ci const struct drm_display_info *info, 1178c2ecf20Sopenharmony_ci const struct drm_display_mode *mode); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /** 1208c2ecf20Sopenharmony_ci * @mode_fixup: 1218c2ecf20Sopenharmony_ci * 1228c2ecf20Sopenharmony_ci * This callback is used to validate and adjust a mode. The parameter 1238c2ecf20Sopenharmony_ci * mode is the display mode that should be fed to the next element in 1248c2ecf20Sopenharmony_ci * the display chain, either the final &drm_connector or the next 1258c2ecf20Sopenharmony_ci * &drm_bridge. The parameter adjusted_mode is the input mode the bridge 1268c2ecf20Sopenharmony_ci * requires. It can be modified by this callback and does not need to 1278c2ecf20Sopenharmony_ci * match mode. See also &drm_crtc_state.adjusted_mode for more details. 1288c2ecf20Sopenharmony_ci * 1298c2ecf20Sopenharmony_ci * This is the only hook that allows a bridge to reject a modeset. If 1308c2ecf20Sopenharmony_ci * this function passes all other callbacks must succeed for this 1318c2ecf20Sopenharmony_ci * configuration. 1328c2ecf20Sopenharmony_ci * 1338c2ecf20Sopenharmony_ci * The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup() 1348c2ecf20Sopenharmony_ci * is not called when &drm_bridge_funcs.atomic_check() is implemented, 1358c2ecf20Sopenharmony_ci * so only one of them should be provided. 1368c2ecf20Sopenharmony_ci * 1378c2ecf20Sopenharmony_ci * NOTE: 1388c2ecf20Sopenharmony_ci * 1398c2ecf20Sopenharmony_ci * This function is called in the check phase of atomic modesets, which 1408c2ecf20Sopenharmony_ci * can be aborted for any reason (including on userspace's request to 1418c2ecf20Sopenharmony_ci * just check whether a configuration would be possible). Drivers MUST 1428c2ecf20Sopenharmony_ci * NOT touch any persistent state (hardware or software) or data 1438c2ecf20Sopenharmony_ci * structures except the passed in @state parameter. 1448c2ecf20Sopenharmony_ci * 1458c2ecf20Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 1468c2ecf20Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 1478c2ecf20Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 1488c2ecf20Sopenharmony_ci * that modes are filtered consistently put any bridge constraints and 1498c2ecf20Sopenharmony_ci * limits checks into @mode_valid. 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * RETURNS: 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * True if an acceptable configuration is possible, false if the modeset 1548c2ecf20Sopenharmony_ci * operation should be rejected. 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ci bool (*mode_fixup)(struct drm_bridge *bridge, 1578c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 1588c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode); 1598c2ecf20Sopenharmony_ci /** 1608c2ecf20Sopenharmony_ci * @disable: 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * This callback should disable the bridge. It is called right before 1638c2ecf20Sopenharmony_ci * the preceding element in the display pipe is disabled. If the 1648c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called before that 1658c2ecf20Sopenharmony_ci * bridge's @disable vfunc. If the preceding element is a &drm_encoder 1668c2ecf20Sopenharmony_ci * it's called right before the &drm_encoder_helper_funcs.disable, 1678c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.prepare or &drm_encoder_helper_funcs.dpms 1688c2ecf20Sopenharmony_ci * hook. 1698c2ecf20Sopenharmony_ci * 1708c2ecf20Sopenharmony_ci * The bridge can assume that the display pipe (i.e. clocks and timing 1718c2ecf20Sopenharmony_ci * signals) feeding it is still running when this callback is called. 1728c2ecf20Sopenharmony_ci * 1738c2ecf20Sopenharmony_ci * The @disable callback is optional. 1748c2ecf20Sopenharmony_ci */ 1758c2ecf20Sopenharmony_ci void (*disable)(struct drm_bridge *bridge); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci /** 1788c2ecf20Sopenharmony_ci * @post_disable: 1798c2ecf20Sopenharmony_ci * 1808c2ecf20Sopenharmony_ci * This callback should disable the bridge. It is called right after the 1818c2ecf20Sopenharmony_ci * preceding element in the display pipe is disabled. If the preceding 1828c2ecf20Sopenharmony_ci * element is a bridge this means it's called after that bridge's 1838c2ecf20Sopenharmony_ci * @post_disable function. If the preceding element is a &drm_encoder 1848c2ecf20Sopenharmony_ci * it's called right after the encoder's 1858c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.disable, &drm_encoder_helper_funcs.prepare 1868c2ecf20Sopenharmony_ci * or &drm_encoder_helper_funcs.dpms hook. 1878c2ecf20Sopenharmony_ci * 1888c2ecf20Sopenharmony_ci * The bridge must assume that the display pipe (i.e. clocks and timing 1898c2ecf20Sopenharmony_ci * signals) feeding it is no longer running when this callback is 1908c2ecf20Sopenharmony_ci * called. 1918c2ecf20Sopenharmony_ci * 1928c2ecf20Sopenharmony_ci * The @post_disable callback is optional. 1938c2ecf20Sopenharmony_ci */ 1948c2ecf20Sopenharmony_ci void (*post_disable)(struct drm_bridge *bridge); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci /** 1978c2ecf20Sopenharmony_ci * @mode_set: 1988c2ecf20Sopenharmony_ci * 1998c2ecf20Sopenharmony_ci * This callback should set the given mode on the bridge. It is called 2008c2ecf20Sopenharmony_ci * after the @mode_set callback for the preceding element in the display 2018c2ecf20Sopenharmony_ci * pipeline has been called already. If the bridge is the first element 2028c2ecf20Sopenharmony_ci * then this would be &drm_encoder_helper_funcs.mode_set. The display 2038c2ecf20Sopenharmony_ci * pipe (i.e. clocks and timing signals) is off when this function is 2048c2ecf20Sopenharmony_ci * called. 2058c2ecf20Sopenharmony_ci * 2068c2ecf20Sopenharmony_ci * The adjusted_mode parameter is the mode output by the CRTC for the 2078c2ecf20Sopenharmony_ci * first bridge in the chain. It can be different from the mode 2088c2ecf20Sopenharmony_ci * parameter that contains the desired mode for the connector at the end 2098c2ecf20Sopenharmony_ci * of the bridges chain, for instance when the first bridge in the chain 2108c2ecf20Sopenharmony_ci * performs scaling. The adjusted mode is mostly useful for the first 2118c2ecf20Sopenharmony_ci * bridge in the chain and is likely irrelevant for the other bridges. 2128c2ecf20Sopenharmony_ci * 2138c2ecf20Sopenharmony_ci * For atomic drivers the adjusted_mode is the mode stored in 2148c2ecf20Sopenharmony_ci * &drm_crtc_state.adjusted_mode. 2158c2ecf20Sopenharmony_ci * 2168c2ecf20Sopenharmony_ci * NOTE: 2178c2ecf20Sopenharmony_ci * 2188c2ecf20Sopenharmony_ci * If a need arises to store and access modes adjusted for other 2198c2ecf20Sopenharmony_ci * locations than the connection between the CRTC and the first bridge, 2208c2ecf20Sopenharmony_ci * the DRM framework will have to be extended with DRM bridge states. 2218c2ecf20Sopenharmony_ci */ 2228c2ecf20Sopenharmony_ci void (*mode_set)(struct drm_bridge *bridge, 2238c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 2248c2ecf20Sopenharmony_ci const struct drm_display_mode *adjusted_mode); 2258c2ecf20Sopenharmony_ci /** 2268c2ecf20Sopenharmony_ci * @pre_enable: 2278c2ecf20Sopenharmony_ci * 2288c2ecf20Sopenharmony_ci * This callback should enable the bridge. It is called right before 2298c2ecf20Sopenharmony_ci * the preceding element in the display pipe is enabled. If the 2308c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called before that 2318c2ecf20Sopenharmony_ci * bridge's @pre_enable function. If the preceding element is a 2328c2ecf20Sopenharmony_ci * &drm_encoder it's called right before the encoder's 2338c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or 2348c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.dpms hook. 2358c2ecf20Sopenharmony_ci * 2368c2ecf20Sopenharmony_ci * The display pipe (i.e. clocks and timing signals) feeding this bridge 2378c2ecf20Sopenharmony_ci * will not yet be running when this callback is called. The bridge must 2388c2ecf20Sopenharmony_ci * not enable the display link feeding the next bridge in the chain (if 2398c2ecf20Sopenharmony_ci * there is one) when this callback is called. 2408c2ecf20Sopenharmony_ci * 2418c2ecf20Sopenharmony_ci * The @pre_enable callback is optional. 2428c2ecf20Sopenharmony_ci */ 2438c2ecf20Sopenharmony_ci void (*pre_enable)(struct drm_bridge *bridge); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci /** 2468c2ecf20Sopenharmony_ci * @enable: 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * This callback should enable the bridge. It is called right after 2498c2ecf20Sopenharmony_ci * the preceding element in the display pipe is enabled. If the 2508c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called after that 2518c2ecf20Sopenharmony_ci * bridge's @enable function. If the preceding element is a 2528c2ecf20Sopenharmony_ci * &drm_encoder it's called right after the encoder's 2538c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or 2548c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.dpms hook. 2558c2ecf20Sopenharmony_ci * 2568c2ecf20Sopenharmony_ci * The bridge can assume that the display pipe (i.e. clocks and timing 2578c2ecf20Sopenharmony_ci * signals) feeding it is running when this callback is called. This 2588c2ecf20Sopenharmony_ci * callback must enable the display link feeding the next bridge in the 2598c2ecf20Sopenharmony_ci * chain if there is one. 2608c2ecf20Sopenharmony_ci * 2618c2ecf20Sopenharmony_ci * The @enable callback is optional. 2628c2ecf20Sopenharmony_ci */ 2638c2ecf20Sopenharmony_ci void (*enable)(struct drm_bridge *bridge); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci /** 2668c2ecf20Sopenharmony_ci * @atomic_pre_enable: 2678c2ecf20Sopenharmony_ci * 2688c2ecf20Sopenharmony_ci * This callback should enable the bridge. It is called right before 2698c2ecf20Sopenharmony_ci * the preceding element in the display pipe is enabled. If the 2708c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called before that 2718c2ecf20Sopenharmony_ci * bridge's @atomic_pre_enable or @pre_enable function. If the preceding 2728c2ecf20Sopenharmony_ci * element is a &drm_encoder it's called right before the encoder's 2738c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.atomic_enable hook. 2748c2ecf20Sopenharmony_ci * 2758c2ecf20Sopenharmony_ci * The display pipe (i.e. clocks and timing signals) feeding this bridge 2768c2ecf20Sopenharmony_ci * will not yet be running when this callback is called. The bridge must 2778c2ecf20Sopenharmony_ci * not enable the display link feeding the next bridge in the chain (if 2788c2ecf20Sopenharmony_ci * there is one) when this callback is called. 2798c2ecf20Sopenharmony_ci * 2808c2ecf20Sopenharmony_ci * Note that this function will only be invoked in the context of an 2818c2ecf20Sopenharmony_ci * atomic commit. It will not be invoked from 2828c2ecf20Sopenharmony_ci * &drm_bridge_chain_pre_enable. It would be prudent to also provide an 2838c2ecf20Sopenharmony_ci * implementation of @pre_enable if you are expecting driver calls into 2848c2ecf20Sopenharmony_ci * &drm_bridge_chain_pre_enable. 2858c2ecf20Sopenharmony_ci * 2868c2ecf20Sopenharmony_ci * The @atomic_pre_enable callback is optional. 2878c2ecf20Sopenharmony_ci */ 2888c2ecf20Sopenharmony_ci void (*atomic_pre_enable)(struct drm_bridge *bridge, 2898c2ecf20Sopenharmony_ci struct drm_bridge_state *old_bridge_state); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci /** 2928c2ecf20Sopenharmony_ci * @atomic_enable: 2938c2ecf20Sopenharmony_ci * 2948c2ecf20Sopenharmony_ci * This callback should enable the bridge. It is called right after 2958c2ecf20Sopenharmony_ci * the preceding element in the display pipe is enabled. If the 2968c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called after that 2978c2ecf20Sopenharmony_ci * bridge's @atomic_enable or @enable function. If the preceding element 2988c2ecf20Sopenharmony_ci * is a &drm_encoder it's called right after the encoder's 2998c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.atomic_enable hook. 3008c2ecf20Sopenharmony_ci * 3018c2ecf20Sopenharmony_ci * The bridge can assume that the display pipe (i.e. clocks and timing 3028c2ecf20Sopenharmony_ci * signals) feeding it is running when this callback is called. This 3038c2ecf20Sopenharmony_ci * callback must enable the display link feeding the next bridge in the 3048c2ecf20Sopenharmony_ci * chain if there is one. 3058c2ecf20Sopenharmony_ci * 3068c2ecf20Sopenharmony_ci * Note that this function will only be invoked in the context of an 3078c2ecf20Sopenharmony_ci * atomic commit. It will not be invoked from &drm_bridge_chain_enable. 3088c2ecf20Sopenharmony_ci * It would be prudent to also provide an implementation of @enable if 3098c2ecf20Sopenharmony_ci * you are expecting driver calls into &drm_bridge_chain_enable. 3108c2ecf20Sopenharmony_ci * 3118c2ecf20Sopenharmony_ci * The @atomic_enable callback is optional. 3128c2ecf20Sopenharmony_ci */ 3138c2ecf20Sopenharmony_ci void (*atomic_enable)(struct drm_bridge *bridge, 3148c2ecf20Sopenharmony_ci struct drm_bridge_state *old_bridge_state); 3158c2ecf20Sopenharmony_ci /** 3168c2ecf20Sopenharmony_ci * @atomic_disable: 3178c2ecf20Sopenharmony_ci * 3188c2ecf20Sopenharmony_ci * This callback should disable the bridge. It is called right before 3198c2ecf20Sopenharmony_ci * the preceding element in the display pipe is disabled. If the 3208c2ecf20Sopenharmony_ci * preceding element is a bridge this means it's called before that 3218c2ecf20Sopenharmony_ci * bridge's @atomic_disable or @disable vfunc. If the preceding element 3228c2ecf20Sopenharmony_ci * is a &drm_encoder it's called right before the 3238c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.atomic_disable hook. 3248c2ecf20Sopenharmony_ci * 3258c2ecf20Sopenharmony_ci * The bridge can assume that the display pipe (i.e. clocks and timing 3268c2ecf20Sopenharmony_ci * signals) feeding it is still running when this callback is called. 3278c2ecf20Sopenharmony_ci * 3288c2ecf20Sopenharmony_ci * Note that this function will only be invoked in the context of an 3298c2ecf20Sopenharmony_ci * atomic commit. It will not be invoked from 3308c2ecf20Sopenharmony_ci * &drm_bridge_chain_disable. It would be prudent to also provide an 3318c2ecf20Sopenharmony_ci * implementation of @disable if you are expecting driver calls into 3328c2ecf20Sopenharmony_ci * &drm_bridge_chain_disable. 3338c2ecf20Sopenharmony_ci * 3348c2ecf20Sopenharmony_ci * The @atomic_disable callback is optional. 3358c2ecf20Sopenharmony_ci */ 3368c2ecf20Sopenharmony_ci void (*atomic_disable)(struct drm_bridge *bridge, 3378c2ecf20Sopenharmony_ci struct drm_bridge_state *old_bridge_state); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci /** 3408c2ecf20Sopenharmony_ci * @atomic_post_disable: 3418c2ecf20Sopenharmony_ci * 3428c2ecf20Sopenharmony_ci * This callback should disable the bridge. It is called right after the 3438c2ecf20Sopenharmony_ci * preceding element in the display pipe is disabled. If the preceding 3448c2ecf20Sopenharmony_ci * element is a bridge this means it's called after that bridge's 3458c2ecf20Sopenharmony_ci * @atomic_post_disable or @post_disable function. If the preceding 3468c2ecf20Sopenharmony_ci * element is a &drm_encoder it's called right after the encoder's 3478c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.atomic_disable hook. 3488c2ecf20Sopenharmony_ci * 3498c2ecf20Sopenharmony_ci * The bridge must assume that the display pipe (i.e. clocks and timing 3508c2ecf20Sopenharmony_ci * signals) feeding it is no longer running when this callback is 3518c2ecf20Sopenharmony_ci * called. 3528c2ecf20Sopenharmony_ci * 3538c2ecf20Sopenharmony_ci * Note that this function will only be invoked in the context of an 3548c2ecf20Sopenharmony_ci * atomic commit. It will not be invoked from 3558c2ecf20Sopenharmony_ci * &drm_bridge_chain_post_disable. 3568c2ecf20Sopenharmony_ci * It would be prudent to also provide an implementation of 3578c2ecf20Sopenharmony_ci * @post_disable if you are expecting driver calls into 3588c2ecf20Sopenharmony_ci * &drm_bridge_chain_post_disable. 3598c2ecf20Sopenharmony_ci * 3608c2ecf20Sopenharmony_ci * The @atomic_post_disable callback is optional. 3618c2ecf20Sopenharmony_ci */ 3628c2ecf20Sopenharmony_ci void (*atomic_post_disable)(struct drm_bridge *bridge, 3638c2ecf20Sopenharmony_ci struct drm_bridge_state *old_bridge_state); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci /** 3668c2ecf20Sopenharmony_ci * @atomic_duplicate_state: 3678c2ecf20Sopenharmony_ci * 3688c2ecf20Sopenharmony_ci * Duplicate the current bridge state object (which is guaranteed to be 3698c2ecf20Sopenharmony_ci * non-NULL). 3708c2ecf20Sopenharmony_ci * 3718c2ecf20Sopenharmony_ci * The atomic_duplicate_state hook is mandatory if the bridge 3728c2ecf20Sopenharmony_ci * implements any of the atomic hooks, and should be left unassigned 3738c2ecf20Sopenharmony_ci * otherwise. For bridges that don't subclass &drm_bridge_state, the 3748c2ecf20Sopenharmony_ci * drm_atomic_helper_bridge_duplicate_state() helper function shall be 3758c2ecf20Sopenharmony_ci * used to implement this hook. 3768c2ecf20Sopenharmony_ci * 3778c2ecf20Sopenharmony_ci * RETURNS: 3788c2ecf20Sopenharmony_ci * A valid drm_bridge_state object or NULL if the allocation fails. 3798c2ecf20Sopenharmony_ci */ 3808c2ecf20Sopenharmony_ci struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci /** 3838c2ecf20Sopenharmony_ci * @atomic_destroy_state: 3848c2ecf20Sopenharmony_ci * 3858c2ecf20Sopenharmony_ci * Destroy a bridge state object previously allocated by 3868c2ecf20Sopenharmony_ci * &drm_bridge_funcs.atomic_duplicate_state(). 3878c2ecf20Sopenharmony_ci * 3888c2ecf20Sopenharmony_ci * The atomic_destroy_state hook is mandatory if the bridge implements 3898c2ecf20Sopenharmony_ci * any of the atomic hooks, and should be left unassigned otherwise. 3908c2ecf20Sopenharmony_ci * For bridges that don't subclass &drm_bridge_state, the 3918c2ecf20Sopenharmony_ci * drm_atomic_helper_bridge_destroy_state() helper function shall be 3928c2ecf20Sopenharmony_ci * used to implement this hook. 3938c2ecf20Sopenharmony_ci */ 3948c2ecf20Sopenharmony_ci void (*atomic_destroy_state)(struct drm_bridge *bridge, 3958c2ecf20Sopenharmony_ci struct drm_bridge_state *state); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci /** 3988c2ecf20Sopenharmony_ci * @atomic_get_output_bus_fmts: 3998c2ecf20Sopenharmony_ci * 4008c2ecf20Sopenharmony_ci * Return the supported bus formats on the output end of a bridge. 4018c2ecf20Sopenharmony_ci * The returned array must be allocated with kmalloc() and will be 4028c2ecf20Sopenharmony_ci * freed by the caller. If the allocation fails, NULL should be 4038c2ecf20Sopenharmony_ci * returned. num_output_fmts must be set to the returned array size. 4048c2ecf20Sopenharmony_ci * Formats listed in the returned array should be listed in decreasing 4058c2ecf20Sopenharmony_ci * preference order (the core will try all formats until it finds one 4068c2ecf20Sopenharmony_ci * that works). 4078c2ecf20Sopenharmony_ci * 4088c2ecf20Sopenharmony_ci * This method is only called on the last element of the bridge chain 4098c2ecf20Sopenharmony_ci * as part of the bus format negotiation process that happens in 4108c2ecf20Sopenharmony_ci * &drm_atomic_bridge_chain_select_bus_fmts(). 4118c2ecf20Sopenharmony_ci * This method is optional. When not implemented, the core will 4128c2ecf20Sopenharmony_ci * fall back to &drm_connector.display_info.bus_formats[0] if 4138c2ecf20Sopenharmony_ci * &drm_connector.display_info.num_bus_formats > 0, 4148c2ecf20Sopenharmony_ci * or to MEDIA_BUS_FMT_FIXED otherwise. 4158c2ecf20Sopenharmony_ci */ 4168c2ecf20Sopenharmony_ci u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge, 4178c2ecf20Sopenharmony_ci struct drm_bridge_state *bridge_state, 4188c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 4198c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state, 4208c2ecf20Sopenharmony_ci unsigned int *num_output_fmts); 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci /** 4238c2ecf20Sopenharmony_ci * @atomic_get_input_bus_fmts: 4248c2ecf20Sopenharmony_ci * 4258c2ecf20Sopenharmony_ci * Return the supported bus formats on the input end of a bridge for 4268c2ecf20Sopenharmony_ci * a specific output bus format. 4278c2ecf20Sopenharmony_ci * 4288c2ecf20Sopenharmony_ci * The returned array must be allocated with kmalloc() and will be 4298c2ecf20Sopenharmony_ci * freed by the caller. If the allocation fails, NULL should be 4308c2ecf20Sopenharmony_ci * returned. num_input_fmts must be set to the returned array size. 4318c2ecf20Sopenharmony_ci * Formats listed in the returned array should be listed in decreasing 4328c2ecf20Sopenharmony_ci * preference order (the core will try all formats until it finds one 4338c2ecf20Sopenharmony_ci * that works). When the format is not supported NULL should be 4348c2ecf20Sopenharmony_ci * returned and num_input_fmts should be set to 0. 4358c2ecf20Sopenharmony_ci * 4368c2ecf20Sopenharmony_ci * This method is called on all elements of the bridge chain as part of 4378c2ecf20Sopenharmony_ci * the bus format negotiation process that happens in 4388c2ecf20Sopenharmony_ci * drm_atomic_bridge_chain_select_bus_fmts(). 4398c2ecf20Sopenharmony_ci * This method is optional. When not implemented, the core will bypass 4408c2ecf20Sopenharmony_ci * bus format negotiation on this element of the bridge without 4418c2ecf20Sopenharmony_ci * failing, and the previous element in the chain will be passed 4428c2ecf20Sopenharmony_ci * MEDIA_BUS_FMT_FIXED as its output bus format. 4438c2ecf20Sopenharmony_ci * 4448c2ecf20Sopenharmony_ci * Bridge drivers that need to support being linked to bridges that are 4458c2ecf20Sopenharmony_ci * not supporting bus format negotiation should handle the 4468c2ecf20Sopenharmony_ci * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a 4478c2ecf20Sopenharmony_ci * sensible default value or extracting this information from somewhere 4488c2ecf20Sopenharmony_ci * else (FW property, &drm_display_mode, &drm_display_info, ...) 4498c2ecf20Sopenharmony_ci * 4508c2ecf20Sopenharmony_ci * Note: Even if input format selection on the first bridge has no 4518c2ecf20Sopenharmony_ci * impact on the negotiation process (bus format negotiation stops once 4528c2ecf20Sopenharmony_ci * we reach the first element of the chain), drivers are expected to 4538c2ecf20Sopenharmony_ci * return accurate input formats as the input format may be used to 4548c2ecf20Sopenharmony_ci * configure the CRTC output appropriately. 4558c2ecf20Sopenharmony_ci */ 4568c2ecf20Sopenharmony_ci u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge, 4578c2ecf20Sopenharmony_ci struct drm_bridge_state *bridge_state, 4588c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 4598c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state, 4608c2ecf20Sopenharmony_ci u32 output_fmt, 4618c2ecf20Sopenharmony_ci unsigned int *num_input_fmts); 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci /** 4648c2ecf20Sopenharmony_ci * @atomic_check: 4658c2ecf20Sopenharmony_ci * 4668c2ecf20Sopenharmony_ci * This method is responsible for checking bridge state correctness. 4678c2ecf20Sopenharmony_ci * It can also check the state of the surrounding components in chain 4688c2ecf20Sopenharmony_ci * to make sure the whole pipeline can work properly. 4698c2ecf20Sopenharmony_ci * 4708c2ecf20Sopenharmony_ci * &drm_bridge_funcs.atomic_check() hooks are called in reverse 4718c2ecf20Sopenharmony_ci * order (from the last to the first bridge). 4728c2ecf20Sopenharmony_ci * 4738c2ecf20Sopenharmony_ci * This method is optional. &drm_bridge_funcs.mode_fixup() is not 4748c2ecf20Sopenharmony_ci * called when &drm_bridge_funcs.atomic_check() is implemented, so only 4758c2ecf20Sopenharmony_ci * one of them should be provided. 4768c2ecf20Sopenharmony_ci * 4778c2ecf20Sopenharmony_ci * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or 4788c2ecf20Sopenharmony_ci * &drm_bridge_state.output_bus_cfg.flags it should happen in 4798c2ecf20Sopenharmony_ci * this function. By default the &drm_bridge_state.output_bus_cfg.flags 4808c2ecf20Sopenharmony_ci * field is set to the next bridge 4818c2ecf20Sopenharmony_ci * &drm_bridge_state.input_bus_cfg.flags value or 4828c2ecf20Sopenharmony_ci * &drm_connector.display_info.bus_flags if the bridge is the last 4838c2ecf20Sopenharmony_ci * element in the chain. 4848c2ecf20Sopenharmony_ci * 4858c2ecf20Sopenharmony_ci * RETURNS: 4868c2ecf20Sopenharmony_ci * zero if the check passed, a negative error code otherwise. 4878c2ecf20Sopenharmony_ci */ 4888c2ecf20Sopenharmony_ci int (*atomic_check)(struct drm_bridge *bridge, 4898c2ecf20Sopenharmony_ci struct drm_bridge_state *bridge_state, 4908c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 4918c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci /** 4948c2ecf20Sopenharmony_ci * @atomic_reset: 4958c2ecf20Sopenharmony_ci * 4968c2ecf20Sopenharmony_ci * Reset the bridge to a predefined state (or retrieve its current 4978c2ecf20Sopenharmony_ci * state) and return a &drm_bridge_state object matching this state. 4988c2ecf20Sopenharmony_ci * This function is called at attach time. 4998c2ecf20Sopenharmony_ci * 5008c2ecf20Sopenharmony_ci * The atomic_reset hook is mandatory if the bridge implements any of 5018c2ecf20Sopenharmony_ci * the atomic hooks, and should be left unassigned otherwise. For 5028c2ecf20Sopenharmony_ci * bridges that don't subclass &drm_bridge_state, the 5038c2ecf20Sopenharmony_ci * drm_atomic_helper_bridge_reset() helper function shall be used to 5048c2ecf20Sopenharmony_ci * implement this hook. 5058c2ecf20Sopenharmony_ci * 5068c2ecf20Sopenharmony_ci * Note that the atomic_reset() semantics is not exactly matching the 5078c2ecf20Sopenharmony_ci * reset() semantics found on other components (connector, plane, ...). 5088c2ecf20Sopenharmony_ci * 5098c2ecf20Sopenharmony_ci * 1. The reset operation happens when the bridge is attached, not when 5108c2ecf20Sopenharmony_ci * drm_mode_config_reset() is called 5118c2ecf20Sopenharmony_ci * 2. It's meant to be used exclusively on bridges that have been 5128c2ecf20Sopenharmony_ci * converted to the ATOMIC API 5138c2ecf20Sopenharmony_ci * 5148c2ecf20Sopenharmony_ci * RETURNS: 5158c2ecf20Sopenharmony_ci * A valid drm_bridge_state object in case of success, an ERR_PTR() 5168c2ecf20Sopenharmony_ci * giving the reason of the failure otherwise. 5178c2ecf20Sopenharmony_ci */ 5188c2ecf20Sopenharmony_ci struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge); 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci /** 5218c2ecf20Sopenharmony_ci * @detect: 5228c2ecf20Sopenharmony_ci * 5238c2ecf20Sopenharmony_ci * Check if anything is attached to the bridge output. 5248c2ecf20Sopenharmony_ci * 5258c2ecf20Sopenharmony_ci * This callback is optional, if not implemented the bridge will be 5268c2ecf20Sopenharmony_ci * considered as always having a component attached to its output. 5278c2ecf20Sopenharmony_ci * Bridges that implement this callback shall set the 5288c2ecf20Sopenharmony_ci * DRM_BRIDGE_OP_DETECT flag in their &drm_bridge->ops. 5298c2ecf20Sopenharmony_ci * 5308c2ecf20Sopenharmony_ci * RETURNS: 5318c2ecf20Sopenharmony_ci * 5328c2ecf20Sopenharmony_ci * drm_connector_status indicating the bridge output status. 5338c2ecf20Sopenharmony_ci */ 5348c2ecf20Sopenharmony_ci enum drm_connector_status (*detect)(struct drm_bridge *bridge); 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci /** 5378c2ecf20Sopenharmony_ci * @get_modes: 5388c2ecf20Sopenharmony_ci * 5398c2ecf20Sopenharmony_ci * Fill all modes currently valid for the sink into the &drm_connector 5408c2ecf20Sopenharmony_ci * with drm_mode_probed_add(). 5418c2ecf20Sopenharmony_ci * 5428c2ecf20Sopenharmony_ci * The @get_modes callback is mostly intended to support non-probeable 5438c2ecf20Sopenharmony_ci * displays such as many fixed panels. Bridges that support reading 5448c2ecf20Sopenharmony_ci * EDID shall leave @get_modes unimplemented and implement the 5458c2ecf20Sopenharmony_ci * &drm_bridge_funcs->get_edid callback instead. 5468c2ecf20Sopenharmony_ci * 5478c2ecf20Sopenharmony_ci * This callback is optional. Bridges that implement it shall set the 5488c2ecf20Sopenharmony_ci * DRM_BRIDGE_OP_MODES flag in their &drm_bridge->ops. 5498c2ecf20Sopenharmony_ci * 5508c2ecf20Sopenharmony_ci * The connector parameter shall be used for the sole purpose of 5518c2ecf20Sopenharmony_ci * filling modes, and shall not be stored internally by bridge drivers 5528c2ecf20Sopenharmony_ci * for future usage. 5538c2ecf20Sopenharmony_ci * 5548c2ecf20Sopenharmony_ci * RETURNS: 5558c2ecf20Sopenharmony_ci * 5568c2ecf20Sopenharmony_ci * The number of modes added by calling drm_mode_probed_add(). 5578c2ecf20Sopenharmony_ci */ 5588c2ecf20Sopenharmony_ci int (*get_modes)(struct drm_bridge *bridge, 5598c2ecf20Sopenharmony_ci struct drm_connector *connector); 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci /** 5628c2ecf20Sopenharmony_ci * @get_edid: 5638c2ecf20Sopenharmony_ci * 5648c2ecf20Sopenharmony_ci * Read and parse the EDID data of the connected display. 5658c2ecf20Sopenharmony_ci * 5668c2ecf20Sopenharmony_ci * The @get_edid callback is the preferred way of reporting mode 5678c2ecf20Sopenharmony_ci * information for a display connected to the bridge output. Bridges 5688c2ecf20Sopenharmony_ci * that support reading EDID shall implement this callback and leave 5698c2ecf20Sopenharmony_ci * the @get_modes callback unimplemented. 5708c2ecf20Sopenharmony_ci * 5718c2ecf20Sopenharmony_ci * The caller of this operation shall first verify the output 5728c2ecf20Sopenharmony_ci * connection status and refrain from reading EDID from a disconnected 5738c2ecf20Sopenharmony_ci * output. 5748c2ecf20Sopenharmony_ci * 5758c2ecf20Sopenharmony_ci * This callback is optional. Bridges that implement it shall set the 5768c2ecf20Sopenharmony_ci * DRM_BRIDGE_OP_EDID flag in their &drm_bridge->ops. 5778c2ecf20Sopenharmony_ci * 5788c2ecf20Sopenharmony_ci * The connector parameter shall be used for the sole purpose of EDID 5798c2ecf20Sopenharmony_ci * retrieval and parsing, and shall not be stored internally by bridge 5808c2ecf20Sopenharmony_ci * drivers for future usage. 5818c2ecf20Sopenharmony_ci * 5828c2ecf20Sopenharmony_ci * RETURNS: 5838c2ecf20Sopenharmony_ci * 5848c2ecf20Sopenharmony_ci * An edid structure newly allocated with kmalloc() (or similar) on 5858c2ecf20Sopenharmony_ci * success, or NULL otherwise. The caller is responsible for freeing 5868c2ecf20Sopenharmony_ci * the returned edid structure with kfree(). 5878c2ecf20Sopenharmony_ci */ 5888c2ecf20Sopenharmony_ci struct edid *(*get_edid)(struct drm_bridge *bridge, 5898c2ecf20Sopenharmony_ci struct drm_connector *connector); 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci /** 5928c2ecf20Sopenharmony_ci * @hpd_notify: 5938c2ecf20Sopenharmony_ci * 5948c2ecf20Sopenharmony_ci * Notify the bridge of hot plug detection. 5958c2ecf20Sopenharmony_ci * 5968c2ecf20Sopenharmony_ci * This callback is optional, it may be implemented by bridges that 5978c2ecf20Sopenharmony_ci * need to be notified of display connection or disconnection for 5988c2ecf20Sopenharmony_ci * internal reasons. One use case is to reset the internal state of CEC 5998c2ecf20Sopenharmony_ci * controllers for HDMI bridges. 6008c2ecf20Sopenharmony_ci */ 6018c2ecf20Sopenharmony_ci void (*hpd_notify)(struct drm_bridge *bridge, 6028c2ecf20Sopenharmony_ci enum drm_connector_status status); 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci /** 6058c2ecf20Sopenharmony_ci * @hpd_enable: 6068c2ecf20Sopenharmony_ci * 6078c2ecf20Sopenharmony_ci * Enable hot plug detection. From now on the bridge shall call 6088c2ecf20Sopenharmony_ci * drm_bridge_hpd_notify() each time a change is detected in the output 6098c2ecf20Sopenharmony_ci * connection status, until hot plug detection gets disabled with 6108c2ecf20Sopenharmony_ci * @hpd_disable. 6118c2ecf20Sopenharmony_ci * 6128c2ecf20Sopenharmony_ci * This callback is optional and shall only be implemented by bridges 6138c2ecf20Sopenharmony_ci * that support hot-plug notification without polling. Bridges that 6148c2ecf20Sopenharmony_ci * implement it shall also implement the @hpd_disable callback and set 6158c2ecf20Sopenharmony_ci * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. 6168c2ecf20Sopenharmony_ci */ 6178c2ecf20Sopenharmony_ci void (*hpd_enable)(struct drm_bridge *bridge); 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci /** 6208c2ecf20Sopenharmony_ci * @hpd_disable: 6218c2ecf20Sopenharmony_ci * 6228c2ecf20Sopenharmony_ci * Disable hot plug detection. Once this function returns the bridge 6238c2ecf20Sopenharmony_ci * shall not call drm_bridge_hpd_notify() when a change in the output 6248c2ecf20Sopenharmony_ci * connection status occurs. 6258c2ecf20Sopenharmony_ci * 6268c2ecf20Sopenharmony_ci * This callback is optional and shall only be implemented by bridges 6278c2ecf20Sopenharmony_ci * that support hot-plug notification without polling. Bridges that 6288c2ecf20Sopenharmony_ci * implement it shall also implement the @hpd_enable callback and set 6298c2ecf20Sopenharmony_ci * the DRM_BRIDGE_OP_HPD flag in their &drm_bridge->ops. 6308c2ecf20Sopenharmony_ci */ 6318c2ecf20Sopenharmony_ci void (*hpd_disable)(struct drm_bridge *bridge); 6328c2ecf20Sopenharmony_ci}; 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci/** 6358c2ecf20Sopenharmony_ci * struct drm_bridge_timings - timing information for the bridge 6368c2ecf20Sopenharmony_ci */ 6378c2ecf20Sopenharmony_cistruct drm_bridge_timings { 6388c2ecf20Sopenharmony_ci /** 6398c2ecf20Sopenharmony_ci * @input_bus_flags: 6408c2ecf20Sopenharmony_ci * 6418c2ecf20Sopenharmony_ci * Tells what additional settings for the pixel data on the bus 6428c2ecf20Sopenharmony_ci * this bridge requires (like pixel signal polarity). See also 6438c2ecf20Sopenharmony_ci * &drm_display_info->bus_flags. 6448c2ecf20Sopenharmony_ci */ 6458c2ecf20Sopenharmony_ci u32 input_bus_flags; 6468c2ecf20Sopenharmony_ci /** 6478c2ecf20Sopenharmony_ci * @setup_time_ps: 6488c2ecf20Sopenharmony_ci * 6498c2ecf20Sopenharmony_ci * Defines the time in picoseconds the input data lines must be 6508c2ecf20Sopenharmony_ci * stable before the clock edge. 6518c2ecf20Sopenharmony_ci */ 6528c2ecf20Sopenharmony_ci u32 setup_time_ps; 6538c2ecf20Sopenharmony_ci /** 6548c2ecf20Sopenharmony_ci * @hold_time_ps: 6558c2ecf20Sopenharmony_ci * 6568c2ecf20Sopenharmony_ci * Defines the time in picoseconds taken for the bridge to sample the 6578c2ecf20Sopenharmony_ci * input signal after the clock edge. 6588c2ecf20Sopenharmony_ci */ 6598c2ecf20Sopenharmony_ci u32 hold_time_ps; 6608c2ecf20Sopenharmony_ci /** 6618c2ecf20Sopenharmony_ci * @dual_link: 6628c2ecf20Sopenharmony_ci * 6638c2ecf20Sopenharmony_ci * True if the bus operates in dual-link mode. The exact meaning is 6648c2ecf20Sopenharmony_ci * dependent on the bus type. For LVDS buses, this indicates that even- 6658c2ecf20Sopenharmony_ci * and odd-numbered pixels are received on separate links. 6668c2ecf20Sopenharmony_ci */ 6678c2ecf20Sopenharmony_ci bool dual_link; 6688c2ecf20Sopenharmony_ci}; 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci/** 6718c2ecf20Sopenharmony_ci * enum drm_bridge_ops - Bitmask of operations supported by the bridge 6728c2ecf20Sopenharmony_ci */ 6738c2ecf20Sopenharmony_cienum drm_bridge_ops { 6748c2ecf20Sopenharmony_ci /** 6758c2ecf20Sopenharmony_ci * @DRM_BRIDGE_OP_DETECT: The bridge can detect displays connected to 6768c2ecf20Sopenharmony_ci * its output. Bridges that set this flag shall implement the 6778c2ecf20Sopenharmony_ci * &drm_bridge_funcs->detect callback. 6788c2ecf20Sopenharmony_ci */ 6798c2ecf20Sopenharmony_ci DRM_BRIDGE_OP_DETECT = BIT(0), 6808c2ecf20Sopenharmony_ci /** 6818c2ecf20Sopenharmony_ci * @DRM_BRIDGE_OP_EDID: The bridge can retrieve the EDID of the display 6828c2ecf20Sopenharmony_ci * connected to its output. Bridges that set this flag shall implement 6838c2ecf20Sopenharmony_ci * the &drm_bridge_funcs->get_edid callback. 6848c2ecf20Sopenharmony_ci */ 6858c2ecf20Sopenharmony_ci DRM_BRIDGE_OP_EDID = BIT(1), 6868c2ecf20Sopenharmony_ci /** 6878c2ecf20Sopenharmony_ci * @DRM_BRIDGE_OP_HPD: The bridge can detect hot-plug and hot-unplug 6888c2ecf20Sopenharmony_ci * without requiring polling. Bridges that set this flag shall 6898c2ecf20Sopenharmony_ci * implement the &drm_bridge_funcs->hpd_enable and 6908c2ecf20Sopenharmony_ci * &drm_bridge_funcs->hpd_disable callbacks if they support enabling 6918c2ecf20Sopenharmony_ci * and disabling hot-plug detection dynamically. 6928c2ecf20Sopenharmony_ci */ 6938c2ecf20Sopenharmony_ci DRM_BRIDGE_OP_HPD = BIT(2), 6948c2ecf20Sopenharmony_ci /** 6958c2ecf20Sopenharmony_ci * @DRM_BRIDGE_OP_MODES: The bridge can retrieve the modes supported 6968c2ecf20Sopenharmony_ci * by the display at its output. This does not include reading EDID 6978c2ecf20Sopenharmony_ci * which is separately covered by @DRM_BRIDGE_OP_EDID. Bridges that set 6988c2ecf20Sopenharmony_ci * this flag shall implement the &drm_bridge_funcs->get_modes callback. 6998c2ecf20Sopenharmony_ci */ 7008c2ecf20Sopenharmony_ci DRM_BRIDGE_OP_MODES = BIT(3), 7018c2ecf20Sopenharmony_ci}; 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci/** 7048c2ecf20Sopenharmony_ci * struct drm_bridge - central DRM bridge control structure 7058c2ecf20Sopenharmony_ci */ 7068c2ecf20Sopenharmony_cistruct drm_bridge { 7078c2ecf20Sopenharmony_ci /** @base: inherit from &drm_private_object */ 7088c2ecf20Sopenharmony_ci struct drm_private_obj base; 7098c2ecf20Sopenharmony_ci /** @dev: DRM device this bridge belongs to */ 7108c2ecf20Sopenharmony_ci struct drm_device *dev; 7118c2ecf20Sopenharmony_ci /** @encoder: encoder to which this bridge is connected */ 7128c2ecf20Sopenharmony_ci struct drm_encoder *encoder; 7138c2ecf20Sopenharmony_ci /** @chain_node: used to form a bridge chain */ 7148c2ecf20Sopenharmony_ci struct list_head chain_node; 7158c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 7168c2ecf20Sopenharmony_ci /** @of_node: device node pointer to the bridge */ 7178c2ecf20Sopenharmony_ci struct device_node *of_node; 7188c2ecf20Sopenharmony_ci#endif 7198c2ecf20Sopenharmony_ci /** @list: to keep track of all added bridges */ 7208c2ecf20Sopenharmony_ci struct list_head list; 7218c2ecf20Sopenharmony_ci /** 7228c2ecf20Sopenharmony_ci * @timings: 7238c2ecf20Sopenharmony_ci * 7248c2ecf20Sopenharmony_ci * the timing specification for the bridge, if any (may be NULL) 7258c2ecf20Sopenharmony_ci */ 7268c2ecf20Sopenharmony_ci const struct drm_bridge_timings *timings; 7278c2ecf20Sopenharmony_ci /** @funcs: control functions */ 7288c2ecf20Sopenharmony_ci const struct drm_bridge_funcs *funcs; 7298c2ecf20Sopenharmony_ci /** @driver_private: pointer to the bridge driver's internal context */ 7308c2ecf20Sopenharmony_ci void *driver_private; 7318c2ecf20Sopenharmony_ci /** @ops: bitmask of operations supported by the bridge */ 7328c2ecf20Sopenharmony_ci enum drm_bridge_ops ops; 7338c2ecf20Sopenharmony_ci /** 7348c2ecf20Sopenharmony_ci * @type: Type of the connection at the bridge output 7358c2ecf20Sopenharmony_ci * (DRM_MODE_CONNECTOR_*). For bridges at the end of this chain this 7368c2ecf20Sopenharmony_ci * identifies the type of connected display. 7378c2ecf20Sopenharmony_ci */ 7388c2ecf20Sopenharmony_ci int type; 7398c2ecf20Sopenharmony_ci /** 7408c2ecf20Sopenharmony_ci * @interlace_allowed: Indicate that the bridge can handle interlaced 7418c2ecf20Sopenharmony_ci * modes. 7428c2ecf20Sopenharmony_ci */ 7438c2ecf20Sopenharmony_ci bool interlace_allowed; 7448c2ecf20Sopenharmony_ci /** 7458c2ecf20Sopenharmony_ci * @ddc: Associated I2C adapter for DDC access, if any. 7468c2ecf20Sopenharmony_ci */ 7478c2ecf20Sopenharmony_ci struct i2c_adapter *ddc; 7488c2ecf20Sopenharmony_ci /** private: */ 7498c2ecf20Sopenharmony_ci /** 7508c2ecf20Sopenharmony_ci * @hpd_mutex: Protects the @hpd_cb and @hpd_data fields. 7518c2ecf20Sopenharmony_ci */ 7528c2ecf20Sopenharmony_ci struct mutex hpd_mutex; 7538c2ecf20Sopenharmony_ci /** 7548c2ecf20Sopenharmony_ci * @hpd_cb: Hot plug detection callback, registered with 7558c2ecf20Sopenharmony_ci * drm_bridge_hpd_enable(). 7568c2ecf20Sopenharmony_ci */ 7578c2ecf20Sopenharmony_ci void (*hpd_cb)(void *data, enum drm_connector_status status); 7588c2ecf20Sopenharmony_ci /** 7598c2ecf20Sopenharmony_ci * @hpd_data: Private data passed to the Hot plug detection callback 7608c2ecf20Sopenharmony_ci * @hpd_cb. 7618c2ecf20Sopenharmony_ci */ 7628c2ecf20Sopenharmony_ci void *hpd_data; 7638c2ecf20Sopenharmony_ci}; 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_cistatic inline struct drm_bridge * 7668c2ecf20Sopenharmony_cidrm_priv_to_bridge(struct drm_private_obj *priv) 7678c2ecf20Sopenharmony_ci{ 7688c2ecf20Sopenharmony_ci return container_of(priv, struct drm_bridge, base); 7698c2ecf20Sopenharmony_ci} 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_civoid drm_bridge_add(struct drm_bridge *bridge); 7728c2ecf20Sopenharmony_civoid drm_bridge_remove(struct drm_bridge *bridge); 7738c2ecf20Sopenharmony_cistruct drm_bridge *of_drm_find_bridge(struct device_node *np); 7748c2ecf20Sopenharmony_ciint drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, 7758c2ecf20Sopenharmony_ci struct drm_bridge *previous, 7768c2ecf20Sopenharmony_ci enum drm_bridge_attach_flags flags); 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci/** 7798c2ecf20Sopenharmony_ci * drm_bridge_get_next_bridge() - Get the next bridge in the chain 7808c2ecf20Sopenharmony_ci * @bridge: bridge object 7818c2ecf20Sopenharmony_ci * 7828c2ecf20Sopenharmony_ci * RETURNS: 7838c2ecf20Sopenharmony_ci * the next bridge in the chain after @bridge, or NULL if @bridge is the last. 7848c2ecf20Sopenharmony_ci */ 7858c2ecf20Sopenharmony_cistatic inline struct drm_bridge * 7868c2ecf20Sopenharmony_cidrm_bridge_get_next_bridge(struct drm_bridge *bridge) 7878c2ecf20Sopenharmony_ci{ 7888c2ecf20Sopenharmony_ci if (list_is_last(&bridge->chain_node, &bridge->encoder->bridge_chain)) 7898c2ecf20Sopenharmony_ci return NULL; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci return list_next_entry(bridge, chain_node); 7928c2ecf20Sopenharmony_ci} 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci/** 7958c2ecf20Sopenharmony_ci * drm_bridge_get_prev_bridge() - Get the previous bridge in the chain 7968c2ecf20Sopenharmony_ci * @bridge: bridge object 7978c2ecf20Sopenharmony_ci * 7988c2ecf20Sopenharmony_ci * RETURNS: 7998c2ecf20Sopenharmony_ci * the previous bridge in the chain, or NULL if @bridge is the first. 8008c2ecf20Sopenharmony_ci */ 8018c2ecf20Sopenharmony_cistatic inline struct drm_bridge * 8028c2ecf20Sopenharmony_cidrm_bridge_get_prev_bridge(struct drm_bridge *bridge) 8038c2ecf20Sopenharmony_ci{ 8048c2ecf20Sopenharmony_ci if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) 8058c2ecf20Sopenharmony_ci return NULL; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci return list_prev_entry(bridge, chain_node); 8088c2ecf20Sopenharmony_ci} 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci/** 8118c2ecf20Sopenharmony_ci * drm_bridge_chain_get_first_bridge() - Get the first bridge in the chain 8128c2ecf20Sopenharmony_ci * @encoder: encoder object 8138c2ecf20Sopenharmony_ci * 8148c2ecf20Sopenharmony_ci * RETURNS: 8158c2ecf20Sopenharmony_ci * the first bridge in the chain, or NULL if @encoder has no bridge attached 8168c2ecf20Sopenharmony_ci * to it. 8178c2ecf20Sopenharmony_ci */ 8188c2ecf20Sopenharmony_cistatic inline struct drm_bridge * 8198c2ecf20Sopenharmony_cidrm_bridge_chain_get_first_bridge(struct drm_encoder *encoder) 8208c2ecf20Sopenharmony_ci{ 8218c2ecf20Sopenharmony_ci return list_first_entry_or_null(&encoder->bridge_chain, 8228c2ecf20Sopenharmony_ci struct drm_bridge, chain_node); 8238c2ecf20Sopenharmony_ci} 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci/** 8268c2ecf20Sopenharmony_ci * drm_for_each_bridge_in_chain() - Iterate over all bridges present in a chain 8278c2ecf20Sopenharmony_ci * @encoder: the encoder to iterate bridges on 8288c2ecf20Sopenharmony_ci * @bridge: a bridge pointer updated to point to the current bridge at each 8298c2ecf20Sopenharmony_ci * iteration 8308c2ecf20Sopenharmony_ci * 8318c2ecf20Sopenharmony_ci * Iterate over all bridges present in the bridge chain attached to @encoder. 8328c2ecf20Sopenharmony_ci */ 8338c2ecf20Sopenharmony_ci#define drm_for_each_bridge_in_chain(encoder, bridge) \ 8348c2ecf20Sopenharmony_ci list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node) 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_cibool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, 8378c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 8388c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode); 8398c2ecf20Sopenharmony_cienum drm_mode_status 8408c2ecf20Sopenharmony_cidrm_bridge_chain_mode_valid(struct drm_bridge *bridge, 8418c2ecf20Sopenharmony_ci const struct drm_display_info *info, 8428c2ecf20Sopenharmony_ci const struct drm_display_mode *mode); 8438c2ecf20Sopenharmony_civoid drm_bridge_chain_disable(struct drm_bridge *bridge); 8448c2ecf20Sopenharmony_civoid drm_bridge_chain_post_disable(struct drm_bridge *bridge); 8458c2ecf20Sopenharmony_civoid drm_bridge_chain_mode_set(struct drm_bridge *bridge, 8468c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 8478c2ecf20Sopenharmony_ci const struct drm_display_mode *adjusted_mode); 8488c2ecf20Sopenharmony_civoid drm_bridge_chain_pre_enable(struct drm_bridge *bridge); 8498c2ecf20Sopenharmony_civoid drm_bridge_chain_enable(struct drm_bridge *bridge); 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ciint drm_atomic_bridge_chain_check(struct drm_bridge *bridge, 8528c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 8538c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state); 8548c2ecf20Sopenharmony_civoid drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, 8558c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 8568c2ecf20Sopenharmony_civoid drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, 8578c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 8588c2ecf20Sopenharmony_civoid drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, 8598c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 8608c2ecf20Sopenharmony_civoid drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, 8618c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ciu32 * 8648c2ecf20Sopenharmony_cidrm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, 8658c2ecf20Sopenharmony_ci struct drm_bridge_state *bridge_state, 8668c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 8678c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state, 8688c2ecf20Sopenharmony_ci u32 output_fmt, 8698c2ecf20Sopenharmony_ci unsigned int *num_input_fmts); 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_cienum drm_connector_status drm_bridge_detect(struct drm_bridge *bridge); 8728c2ecf20Sopenharmony_ciint drm_bridge_get_modes(struct drm_bridge *bridge, 8738c2ecf20Sopenharmony_ci struct drm_connector *connector); 8748c2ecf20Sopenharmony_cistruct edid *drm_bridge_get_edid(struct drm_bridge *bridge, 8758c2ecf20Sopenharmony_ci struct drm_connector *connector); 8768c2ecf20Sopenharmony_civoid drm_bridge_hpd_enable(struct drm_bridge *bridge, 8778c2ecf20Sopenharmony_ci void (*cb)(void *data, 8788c2ecf20Sopenharmony_ci enum drm_connector_status status), 8798c2ecf20Sopenharmony_ci void *data); 8808c2ecf20Sopenharmony_civoid drm_bridge_hpd_disable(struct drm_bridge *bridge); 8818c2ecf20Sopenharmony_civoid drm_bridge_hpd_notify(struct drm_bridge *bridge, 8828c2ecf20Sopenharmony_ci enum drm_connector_status status); 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci#ifdef CONFIG_DRM_PANEL_BRIDGE 8858c2ecf20Sopenharmony_cistruct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); 8868c2ecf20Sopenharmony_cistruct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, 8878c2ecf20Sopenharmony_ci u32 connector_type); 8888c2ecf20Sopenharmony_civoid drm_panel_bridge_remove(struct drm_bridge *bridge); 8898c2ecf20Sopenharmony_cistruct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, 8908c2ecf20Sopenharmony_ci struct drm_panel *panel); 8918c2ecf20Sopenharmony_cistruct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, 8928c2ecf20Sopenharmony_ci struct drm_panel *panel, 8938c2ecf20Sopenharmony_ci u32 connector_type); 8948c2ecf20Sopenharmony_cistruct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge); 8958c2ecf20Sopenharmony_ci#endif 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci#endif 898