18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright © 2006 Keith Packard 38c2ecf20Sopenharmony_ci * Copyright © 2007-2008 Dave Airlie 48c2ecf20Sopenharmony_ci * Copyright © 2007-2008 Intel Corporation 58c2ecf20Sopenharmony_ci * Jesse Barnes <jesse.barnes@intel.com> 68c2ecf20Sopenharmony_ci * Copyright © 2011-2013 Intel Corporation 78c2ecf20Sopenharmony_ci * Copyright © 2015 Intel Corporation 88c2ecf20Sopenharmony_ci * Daniel Vetter <daniel.vetter@ffwll.ch> 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 118c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 128c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 138c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 148c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 158c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 188c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 218c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 228c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 238c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 248c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 258c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 268c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#ifndef __DRM_MODESET_HELPER_VTABLES_H__ 308c2ecf20Sopenharmony_ci#define __DRM_MODESET_HELPER_VTABLES_H__ 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include <drm/drm_crtc.h> 338c2ecf20Sopenharmony_ci#include <drm/drm_encoder.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/** 368c2ecf20Sopenharmony_ci * DOC: overview 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * The DRM mode setting helper functions are common code for drivers to use if 398c2ecf20Sopenharmony_ci * they wish. Drivers are not forced to use this code in their 408c2ecf20Sopenharmony_ci * implementations but it would be useful if the code they do use at least 418c2ecf20Sopenharmony_ci * provides a consistent interface and operation to userspace. Therefore it is 428c2ecf20Sopenharmony_ci * highly recommended to use the provided helpers as much as possible. 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * Because there is only one pointer per modeset object to hold a vfunc table 458c2ecf20Sopenharmony_ci * for helper libraries they are by necessity shared among the different 468c2ecf20Sopenharmony_ci * helpers. 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * To make this clear all the helper vtables are pulled together in this location here. 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cienum mode_set_atomic; 528c2ecf20Sopenharmony_cistruct drm_writeback_connector; 538c2ecf20Sopenharmony_cistruct drm_writeback_job; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/** 568c2ecf20Sopenharmony_ci * struct drm_crtc_helper_funcs - helper operations for CRTCs 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * These hooks are used by the legacy CRTC helpers, the transitional plane 598c2ecf20Sopenharmony_ci * helpers and the new atomic modesetting helpers. 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_cistruct drm_crtc_helper_funcs { 628c2ecf20Sopenharmony_ci /** 638c2ecf20Sopenharmony_ci * @dpms: 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * Callback to control power levels on the CRTC. If the mode passed in 668c2ecf20Sopenharmony_ci * is unsupported, the provider must use the next lowest power level. 678c2ecf20Sopenharmony_ci * This is used by the legacy CRTC helpers to implement DPMS 688c2ecf20Sopenharmony_ci * functionality in drm_helper_connector_dpms(). 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * This callback is also used to disable a CRTC by calling it with 718c2ecf20Sopenharmony_ci * DRM_MODE_DPMS_OFF if the @disable hook isn't used. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 748c2ecf20Sopenharmony_ci * also support using this hook for enabling and disabling a CRTC to 758c2ecf20Sopenharmony_ci * facilitate transitions to atomic, but it is deprecated. Instead 768c2ecf20Sopenharmony_ci * @atomic_enable and @atomic_disable should be used. 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci void (*dpms)(struct drm_crtc *crtc, int mode); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci /** 818c2ecf20Sopenharmony_ci * @prepare: 828c2ecf20Sopenharmony_ci * 838c2ecf20Sopenharmony_ci * This callback should prepare the CRTC for a subsequent modeset, which 848c2ecf20Sopenharmony_ci * in practice means the driver should disable the CRTC if it is 858c2ecf20Sopenharmony_ci * running. Most drivers ended up implementing this by calling their 868c2ecf20Sopenharmony_ci * @dpms hook with DRM_MODE_DPMS_OFF. 878c2ecf20Sopenharmony_ci * 888c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 898c2ecf20Sopenharmony_ci * also support using this hook for disabling a CRTC to facilitate 908c2ecf20Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @atomic_disable 918c2ecf20Sopenharmony_ci * should be used. 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_ci void (*prepare)(struct drm_crtc *crtc); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /** 968c2ecf20Sopenharmony_ci * @commit: 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * This callback should commit the new mode on the CRTC after a modeset, 998c2ecf20Sopenharmony_ci * which in practice means the driver should enable the CRTC. Most 1008c2ecf20Sopenharmony_ci * drivers ended up implementing this by calling their @dpms hook with 1018c2ecf20Sopenharmony_ci * DRM_MODE_DPMS_ON. 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 1048c2ecf20Sopenharmony_ci * also support using this hook for enabling a CRTC to facilitate 1058c2ecf20Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @atomic_enable 1068c2ecf20Sopenharmony_ci * should be used. 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_ci void (*commit)(struct drm_crtc *crtc); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /** 1118c2ecf20Sopenharmony_ci * @mode_valid: 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * This callback is used to check if a specific mode is valid in this 1148c2ecf20Sopenharmony_ci * crtc. This should be implemented if the crtc has some sort of 1158c2ecf20Sopenharmony_ci * restriction in the modes it can display. For example, a given crtc 1168c2ecf20Sopenharmony_ci * may be responsible to set a clock value. If the clock can not 1178c2ecf20Sopenharmony_ci * produce all the values for the available modes then this callback 1188c2ecf20Sopenharmony_ci * can be used to restrict the number of modes to only the ones that 1198c2ecf20Sopenharmony_ci * can be displayed. 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * This hook is used by the probe helpers to filter the mode list in 1228c2ecf20Sopenharmony_ci * drm_helper_probe_single_connector_modes(), and it is used by the 1238c2ecf20Sopenharmony_ci * atomic helpers to validate modes supplied by userspace in 1248c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(). 1258c2ecf20Sopenharmony_ci * 1268c2ecf20Sopenharmony_ci * This function is optional. 1278c2ecf20Sopenharmony_ci * 1288c2ecf20Sopenharmony_ci * NOTE: 1298c2ecf20Sopenharmony_ci * 1308c2ecf20Sopenharmony_ci * Since this function is both called from the check phase of an atomic 1318c2ecf20Sopenharmony_ci * commit, and the mode validation in the probe paths it is not allowed 1328c2ecf20Sopenharmony_ci * to look at anything else but the passed-in mode, and validate it 1338c2ecf20Sopenharmony_ci * against configuration-invariant hardward constraints. Any further 1348c2ecf20Sopenharmony_ci * limits which depend upon the configuration can only be checked in 1358c2ecf20Sopenharmony_ci * @mode_fixup or @atomic_check. 1368c2ecf20Sopenharmony_ci * 1378c2ecf20Sopenharmony_ci * RETURNS: 1388c2ecf20Sopenharmony_ci * 1398c2ecf20Sopenharmony_ci * drm_mode_status Enum 1408c2ecf20Sopenharmony_ci */ 1418c2ecf20Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, 1428c2ecf20Sopenharmony_ci const struct drm_display_mode *mode); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci /** 1458c2ecf20Sopenharmony_ci * @mode_fixup: 1468c2ecf20Sopenharmony_ci * 1478c2ecf20Sopenharmony_ci * This callback is used to validate a mode. The parameter mode is the 1488c2ecf20Sopenharmony_ci * display mode that userspace requested, adjusted_mode is the mode the 1498c2ecf20Sopenharmony_ci * encoders need to be fed with. Note that this is the inverse semantics 1508c2ecf20Sopenharmony_ci * of the meaning for the &drm_encoder and &drm_bridge_funcs.mode_fixup 1518c2ecf20Sopenharmony_ci * vfunc. If the CRTC cannot support the requested conversion from mode 1528c2ecf20Sopenharmony_ci * to adjusted_mode it should reject the modeset. See also 1538c2ecf20Sopenharmony_ci * &drm_crtc_state.adjusted_mode for more details. 1548c2ecf20Sopenharmony_ci * 1558c2ecf20Sopenharmony_ci * This function is used by both legacy CRTC helpers and atomic helpers. 1568c2ecf20Sopenharmony_ci * With atomic helpers it is optional. 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci * NOTE: 1598c2ecf20Sopenharmony_ci * 1608c2ecf20Sopenharmony_ci * This function is called in the check phase of atomic modesets, which 1618c2ecf20Sopenharmony_ci * can be aborted for any reason (including on userspace's request to 1628c2ecf20Sopenharmony_ci * just check whether a configuration would be possible). Atomic drivers 1638c2ecf20Sopenharmony_ci * MUST NOT touch any persistent state (hardware or software) or data 1648c2ecf20Sopenharmony_ci * structures except the passed in adjusted_mode parameter. 1658c2ecf20Sopenharmony_ci * 1668c2ecf20Sopenharmony_ci * This is in contrast to the legacy CRTC helpers where this was 1678c2ecf20Sopenharmony_ci * allowed. 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * Atomic drivers which need to inspect and adjust more state should 1708c2ecf20Sopenharmony_ci * instead use the @atomic_check callback, but note that they're not 1718c2ecf20Sopenharmony_ci * perfectly equivalent: @mode_valid is called from 1728c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(), but @atomic_check is called from 1738c2ecf20Sopenharmony_ci * drm_atomic_helper_check_planes(), because originally it was meant for 1748c2ecf20Sopenharmony_ci * plane update checks only. 1758c2ecf20Sopenharmony_ci * 1768c2ecf20Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 1778c2ecf20Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 1788c2ecf20Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 1798c2ecf20Sopenharmony_ci * that modes are filtered consistently put any CRTC constraints and 1808c2ecf20Sopenharmony_ci * limits checks into @mode_valid. 1818c2ecf20Sopenharmony_ci * 1828c2ecf20Sopenharmony_ci * RETURNS: 1838c2ecf20Sopenharmony_ci * 1848c2ecf20Sopenharmony_ci * True if an acceptable configuration is possible, false if the modeset 1858c2ecf20Sopenharmony_ci * operation should be rejected. 1868c2ecf20Sopenharmony_ci */ 1878c2ecf20Sopenharmony_ci bool (*mode_fixup)(struct drm_crtc *crtc, 1888c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 1898c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci /** 1928c2ecf20Sopenharmony_ci * @mode_set: 1938c2ecf20Sopenharmony_ci * 1948c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers to set a new mode, 1958c2ecf20Sopenharmony_ci * position and framebuffer. Since it ties the primary plane to every 1968c2ecf20Sopenharmony_ci * mode change it is incompatible with universal plane support. And 1978c2ecf20Sopenharmony_ci * since it can't update other planes it's incompatible with atomic 1988c2ecf20Sopenharmony_ci * modeset support. 1998c2ecf20Sopenharmony_ci * 2008c2ecf20Sopenharmony_ci * This callback is only used by CRTC helpers and deprecated. 2018c2ecf20Sopenharmony_ci * 2028c2ecf20Sopenharmony_ci * RETURNS: 2038c2ecf20Sopenharmony_ci * 2048c2ecf20Sopenharmony_ci * 0 on success or a negative error code on failure. 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, 2078c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode, int x, int y, 2088c2ecf20Sopenharmony_ci struct drm_framebuffer *old_fb); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci /** 2118c2ecf20Sopenharmony_ci * @mode_set_nofb: 2128c2ecf20Sopenharmony_ci * 2138c2ecf20Sopenharmony_ci * This callback is used to update the display mode of a CRTC without 2148c2ecf20Sopenharmony_ci * changing anything of the primary plane configuration. This fits the 2158c2ecf20Sopenharmony_ci * requirement of atomic and hence is used by the atomic helpers. It is 2168c2ecf20Sopenharmony_ci * also used by the transitional plane helpers to implement a 2178c2ecf20Sopenharmony_ci * @mode_set hook in drm_helper_crtc_mode_set(). 2188c2ecf20Sopenharmony_ci * 2198c2ecf20Sopenharmony_ci * Note that the display pipe is completely off when this function is 2208c2ecf20Sopenharmony_ci * called. Atomic drivers which need hardware to be running before they 2218c2ecf20Sopenharmony_ci * program the new display mode (e.g. because they implement runtime PM) 2228c2ecf20Sopenharmony_ci * should not use this hook. This is because the helper library calls 2238c2ecf20Sopenharmony_ci * this hook only once per mode change and not every time the display 2248c2ecf20Sopenharmony_ci * pipeline is suspended using either DPMS or the new "ACTIVE" property. 2258c2ecf20Sopenharmony_ci * Which means register values set in this callback might get reset when 2268c2ecf20Sopenharmony_ci * the CRTC is suspended, but not restored. Such drivers should instead 2278c2ecf20Sopenharmony_ci * move all their CRTC setup into the @atomic_enable callback. 2288c2ecf20Sopenharmony_ci * 2298c2ecf20Sopenharmony_ci * This callback is optional. 2308c2ecf20Sopenharmony_ci */ 2318c2ecf20Sopenharmony_ci void (*mode_set_nofb)(struct drm_crtc *crtc); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci /** 2348c2ecf20Sopenharmony_ci * @mode_set_base: 2358c2ecf20Sopenharmony_ci * 2368c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers to set a new 2378c2ecf20Sopenharmony_ci * framebuffer and scanout position. It is optional and used as an 2388c2ecf20Sopenharmony_ci * optimized fast-path instead of a full mode set operation with all the 2398c2ecf20Sopenharmony_ci * resulting flickering. If it is not present 2408c2ecf20Sopenharmony_ci * drm_crtc_helper_set_config() will fall back to a full modeset, using 2418c2ecf20Sopenharmony_ci * the @mode_set callback. Since it can't update other planes it's 2428c2ecf20Sopenharmony_ci * incompatible with atomic modeset support. 2438c2ecf20Sopenharmony_ci * 2448c2ecf20Sopenharmony_ci * This callback is only used by the CRTC helpers and deprecated. 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci * RETURNS: 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * 0 on success or a negative error code on failure. 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ci int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, 2518c2ecf20Sopenharmony_ci struct drm_framebuffer *old_fb); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci /** 2548c2ecf20Sopenharmony_ci * @mode_set_base_atomic: 2558c2ecf20Sopenharmony_ci * 2568c2ecf20Sopenharmony_ci * This callback is used by the fbdev helpers to set a new framebuffer 2578c2ecf20Sopenharmony_ci * and scanout without sleeping, i.e. from an atomic calling context. It 2588c2ecf20Sopenharmony_ci * is only used to implement kgdb support. 2598c2ecf20Sopenharmony_ci * 2608c2ecf20Sopenharmony_ci * This callback is optional and only needed for kgdb support in the fbdev 2618c2ecf20Sopenharmony_ci * helpers. 2628c2ecf20Sopenharmony_ci * 2638c2ecf20Sopenharmony_ci * RETURNS: 2648c2ecf20Sopenharmony_ci * 2658c2ecf20Sopenharmony_ci * 0 on success or a negative error code on failure. 2668c2ecf20Sopenharmony_ci */ 2678c2ecf20Sopenharmony_ci int (*mode_set_base_atomic)(struct drm_crtc *crtc, 2688c2ecf20Sopenharmony_ci struct drm_framebuffer *fb, int x, int y, 2698c2ecf20Sopenharmony_ci enum mode_set_atomic); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci /** 2728c2ecf20Sopenharmony_ci * @disable: 2738c2ecf20Sopenharmony_ci * 2748c2ecf20Sopenharmony_ci * This callback should be used to disable the CRTC. With the atomic 2758c2ecf20Sopenharmony_ci * drivers it is called after all encoders connected to this CRTC have 2768c2ecf20Sopenharmony_ci * been shut off already using their own 2778c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.disable hook. If that sequence is too 2788c2ecf20Sopenharmony_ci * simple drivers can just add their own hooks and call it from this 2798c2ecf20Sopenharmony_ci * CRTC callback here by looping over all encoders connected to it using 2808c2ecf20Sopenharmony_ci * for_each_encoder_on_crtc(). 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci * This hook is used both by legacy CRTC helpers and atomic helpers. 2838c2ecf20Sopenharmony_ci * Atomic drivers don't need to implement it if there's no need to 2848c2ecf20Sopenharmony_ci * disable anything at the CRTC level. To ensure that runtime PM 2858c2ecf20Sopenharmony_ci * handling (using either DPMS or the new "ACTIVE" property) works 2868c2ecf20Sopenharmony_ci * @disable must be the inverse of @atomic_enable for atomic drivers. 2878c2ecf20Sopenharmony_ci * Atomic drivers should consider to use @atomic_disable instead of 2888c2ecf20Sopenharmony_ci * this one. 2898c2ecf20Sopenharmony_ci * 2908c2ecf20Sopenharmony_ci * NOTE: 2918c2ecf20Sopenharmony_ci * 2928c2ecf20Sopenharmony_ci * With legacy CRTC helpers there's a big semantic difference between 2938c2ecf20Sopenharmony_ci * @disable and other hooks (like @prepare or @dpms) used to shut down a 2948c2ecf20Sopenharmony_ci * CRTC: @disable is only called when also logically disabling the 2958c2ecf20Sopenharmony_ci * display pipeline and needs to release any resources acquired in 2968c2ecf20Sopenharmony_ci * @mode_set (like shared PLLs, or again release pinned framebuffers). 2978c2ecf20Sopenharmony_ci * 2988c2ecf20Sopenharmony_ci * Therefore @disable must be the inverse of @mode_set plus @commit for 2998c2ecf20Sopenharmony_ci * drivers still using legacy CRTC helpers, which is different from the 3008c2ecf20Sopenharmony_ci * rules under atomic. 3018c2ecf20Sopenharmony_ci */ 3028c2ecf20Sopenharmony_ci void (*disable)(struct drm_crtc *crtc); 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci /** 3058c2ecf20Sopenharmony_ci * @atomic_check: 3068c2ecf20Sopenharmony_ci * 3078c2ecf20Sopenharmony_ci * Drivers should check plane-update related CRTC constraints in this 3088c2ecf20Sopenharmony_ci * hook. They can also check mode related limitations but need to be 3098c2ecf20Sopenharmony_ci * aware of the calling order, since this hook is used by 3108c2ecf20Sopenharmony_ci * drm_atomic_helper_check_planes() whereas the preparations needed to 3118c2ecf20Sopenharmony_ci * check output routing and the display mode is done in 3128c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(). Therefore drivers that want to 3138c2ecf20Sopenharmony_ci * check output routing and display mode constraints in this callback 3148c2ecf20Sopenharmony_ci * must ensure that drm_atomic_helper_check_modeset() has been called 3158c2ecf20Sopenharmony_ci * beforehand. This is calling order used by the default helper 3168c2ecf20Sopenharmony_ci * implementation in drm_atomic_helper_check(). 3178c2ecf20Sopenharmony_ci * 3188c2ecf20Sopenharmony_ci * When using drm_atomic_helper_check_planes() this hook is called 3198c2ecf20Sopenharmony_ci * after the &drm_plane_helper_funcs.atomic_check hook for planes, which 3208c2ecf20Sopenharmony_ci * allows drivers to assign shared resources requested by planes in this 3218c2ecf20Sopenharmony_ci * callback here. For more complicated dependencies the driver can call 3228c2ecf20Sopenharmony_ci * the provided check helpers multiple times until the computed state 3238c2ecf20Sopenharmony_ci * has a final configuration and everything has been checked. 3248c2ecf20Sopenharmony_ci * 3258c2ecf20Sopenharmony_ci * This function is also allowed to inspect any other object's state and 3268c2ecf20Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 3278c2ecf20Sopenharmony_ci * be taken though to ensure that state check and compute functions for 3288c2ecf20Sopenharmony_ci * these added states are all called, and derived state in other objects 3298c2ecf20Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 3308c2ecf20Sopenharmony_ci * until a maximal configuration is reached. 3318c2ecf20Sopenharmony_ci * 3328c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 3338c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 3348c2ecf20Sopenharmony_ci * 3358c2ecf20Sopenharmony_ci * NOTE: 3368c2ecf20Sopenharmony_ci * 3378c2ecf20Sopenharmony_ci * This function is called in the check phase of an atomic update. The 3388c2ecf20Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 3398c2ecf20Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 3408c2ecf20Sopenharmony_ci * update tracking structure. 3418c2ecf20Sopenharmony_ci * 3428c2ecf20Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 3438c2ecf20Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 3448c2ecf20Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 3458c2ecf20Sopenharmony_ci * that modes are filtered consistently put any CRTC constraints and 3468c2ecf20Sopenharmony_ci * limits checks into @mode_valid. 3478c2ecf20Sopenharmony_ci * 3488c2ecf20Sopenharmony_ci * RETURNS: 3498c2ecf20Sopenharmony_ci * 3508c2ecf20Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 3518c2ecf20Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 3528c2ecf20Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 3538c2ecf20Sopenharmony_ci * deadlock. 3548c2ecf20Sopenharmony_ci */ 3558c2ecf20Sopenharmony_ci int (*atomic_check)(struct drm_crtc *crtc, 3568c2ecf20Sopenharmony_ci struct drm_crtc_state *state); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci /** 3598c2ecf20Sopenharmony_ci * @atomic_begin: 3608c2ecf20Sopenharmony_ci * 3618c2ecf20Sopenharmony_ci * Drivers should prepare for an atomic update of multiple planes on 3628c2ecf20Sopenharmony_ci * a CRTC in this hook. Depending upon hardware this might be vblank 3638c2ecf20Sopenharmony_ci * evasion, blocking updates by setting bits or doing preparatory work 3648c2ecf20Sopenharmony_ci * for e.g. manual update display. 3658c2ecf20Sopenharmony_ci * 3668c2ecf20Sopenharmony_ci * This hook is called before any plane commit functions are called. 3678c2ecf20Sopenharmony_ci * 3688c2ecf20Sopenharmony_ci * Note that the power state of the display pipe when this function is 3698c2ecf20Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 3708c2ecf20Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 3718c2ecf20Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 3728c2ecf20Sopenharmony_ci * 3738c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 3748c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 3758c2ecf20Sopenharmony_ci */ 3768c2ecf20Sopenharmony_ci void (*atomic_begin)(struct drm_crtc *crtc, 3778c2ecf20Sopenharmony_ci struct drm_crtc_state *old_crtc_state); 3788c2ecf20Sopenharmony_ci /** 3798c2ecf20Sopenharmony_ci * @atomic_flush: 3808c2ecf20Sopenharmony_ci * 3818c2ecf20Sopenharmony_ci * Drivers should finalize an atomic update of multiple planes on 3828c2ecf20Sopenharmony_ci * a CRTC in this hook. Depending upon hardware this might include 3838c2ecf20Sopenharmony_ci * checking that vblank evasion was successful, unblocking updates by 3848c2ecf20Sopenharmony_ci * setting bits or setting the GO bit to flush out all updates. 3858c2ecf20Sopenharmony_ci * 3868c2ecf20Sopenharmony_ci * Simple hardware or hardware with special requirements can commit and 3878c2ecf20Sopenharmony_ci * flush out all updates for all planes from this hook and forgo all the 3888c2ecf20Sopenharmony_ci * other commit hooks for plane updates. 3898c2ecf20Sopenharmony_ci * 3908c2ecf20Sopenharmony_ci * This hook is called after any plane commit functions are called. 3918c2ecf20Sopenharmony_ci * 3928c2ecf20Sopenharmony_ci * Note that the power state of the display pipe when this function is 3938c2ecf20Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 3948c2ecf20Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 3958c2ecf20Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 3968c2ecf20Sopenharmony_ci * 3978c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 3988c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 3998c2ecf20Sopenharmony_ci */ 4008c2ecf20Sopenharmony_ci void (*atomic_flush)(struct drm_crtc *crtc, 4018c2ecf20Sopenharmony_ci struct drm_crtc_state *old_crtc_state); 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci /** 4048c2ecf20Sopenharmony_ci * @atomic_enable: 4058c2ecf20Sopenharmony_ci * 4068c2ecf20Sopenharmony_ci * This callback should be used to enable the CRTC. With the atomic 4078c2ecf20Sopenharmony_ci * drivers it is called before all encoders connected to this CRTC are 4088c2ecf20Sopenharmony_ci * enabled through the encoder's own &drm_encoder_helper_funcs.enable 4098c2ecf20Sopenharmony_ci * hook. If that sequence is too simple drivers can just add their own 4108c2ecf20Sopenharmony_ci * hooks and call it from this CRTC callback here by looping over all 4118c2ecf20Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 4128c2ecf20Sopenharmony_ci * 4138c2ecf20Sopenharmony_ci * This hook is used only by atomic helpers, for symmetry with 4148c2ecf20Sopenharmony_ci * @atomic_disable. Atomic drivers don't need to implement it if there's 4158c2ecf20Sopenharmony_ci * no need to enable anything at the CRTC level. To ensure that runtime 4168c2ecf20Sopenharmony_ci * PM handling (using either DPMS or the new "ACTIVE" property) works 4178c2ecf20Sopenharmony_ci * @atomic_enable must be the inverse of @atomic_disable for atomic 4188c2ecf20Sopenharmony_ci * drivers. 4198c2ecf20Sopenharmony_ci * 4208c2ecf20Sopenharmony_ci * Drivers can use the @old_crtc_state input parameter if the operations 4218c2ecf20Sopenharmony_ci * needed to enable the CRTC don't depend solely on the new state but 4228c2ecf20Sopenharmony_ci * also on the transition between the old state and the new state. 4238c2ecf20Sopenharmony_ci * 4248c2ecf20Sopenharmony_ci * This function is optional. 4258c2ecf20Sopenharmony_ci */ 4268c2ecf20Sopenharmony_ci void (*atomic_enable)(struct drm_crtc *crtc, 4278c2ecf20Sopenharmony_ci struct drm_crtc_state *old_crtc_state); 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci /** 4308c2ecf20Sopenharmony_ci * @atomic_disable: 4318c2ecf20Sopenharmony_ci * 4328c2ecf20Sopenharmony_ci * This callback should be used to disable the CRTC. With the atomic 4338c2ecf20Sopenharmony_ci * drivers it is called after all encoders connected to this CRTC have 4348c2ecf20Sopenharmony_ci * been shut off already using their own 4358c2ecf20Sopenharmony_ci * &drm_encoder_helper_funcs.disable hook. If that sequence is too 4368c2ecf20Sopenharmony_ci * simple drivers can just add their own hooks and call it from this 4378c2ecf20Sopenharmony_ci * CRTC callback here by looping over all encoders connected to it using 4388c2ecf20Sopenharmony_ci * for_each_encoder_on_crtc(). 4398c2ecf20Sopenharmony_ci * 4408c2ecf20Sopenharmony_ci * This hook is used only by atomic helpers. Atomic drivers don't 4418c2ecf20Sopenharmony_ci * need to implement it if there's no need to disable anything at the 4428c2ecf20Sopenharmony_ci * CRTC level. 4438c2ecf20Sopenharmony_ci * 4448c2ecf20Sopenharmony_ci * Comparing to @disable, this one provides the additional input 4458c2ecf20Sopenharmony_ci * parameter @old_crtc_state which could be used to access the old 4468c2ecf20Sopenharmony_ci * state. Atomic drivers should consider to use this one instead 4478c2ecf20Sopenharmony_ci * of @disable. 4488c2ecf20Sopenharmony_ci * 4498c2ecf20Sopenharmony_ci * This function is optional. 4508c2ecf20Sopenharmony_ci */ 4518c2ecf20Sopenharmony_ci void (*atomic_disable)(struct drm_crtc *crtc, 4528c2ecf20Sopenharmony_ci struct drm_crtc_state *old_crtc_state); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci /** 4558c2ecf20Sopenharmony_ci * @get_scanout_position: 4568c2ecf20Sopenharmony_ci * 4578c2ecf20Sopenharmony_ci * Called by vblank timestamping code. 4588c2ecf20Sopenharmony_ci * 4598c2ecf20Sopenharmony_ci * Returns the current display scanout position from a CRTC and an 4608c2ecf20Sopenharmony_ci * optional accurate ktime_get() timestamp of when the position was 4618c2ecf20Sopenharmony_ci * measured. Note that this is a helper callback which is only used 4628c2ecf20Sopenharmony_ci * if a driver uses drm_crtc_vblank_helper_get_vblank_timestamp() 4638c2ecf20Sopenharmony_ci * for the @drm_crtc_funcs.get_vblank_timestamp callback. 4648c2ecf20Sopenharmony_ci * 4658c2ecf20Sopenharmony_ci * Parameters: 4668c2ecf20Sopenharmony_ci * 4678c2ecf20Sopenharmony_ci * crtc: 4688c2ecf20Sopenharmony_ci * The CRTC. 4698c2ecf20Sopenharmony_ci * in_vblank_irq: 4708c2ecf20Sopenharmony_ci * True when called from drm_crtc_handle_vblank(). Some drivers 4718c2ecf20Sopenharmony_ci * need to apply some workarounds for gpu-specific vblank irq 4728c2ecf20Sopenharmony_ci * quirks if the flag is set. 4738c2ecf20Sopenharmony_ci * vpos: 4748c2ecf20Sopenharmony_ci * Target location for current vertical scanout position. 4758c2ecf20Sopenharmony_ci * hpos: 4768c2ecf20Sopenharmony_ci * Target location for current horizontal scanout position. 4778c2ecf20Sopenharmony_ci * stime: 4788c2ecf20Sopenharmony_ci * Target location for timestamp taken immediately before 4798c2ecf20Sopenharmony_ci * scanout position query. Can be NULL to skip timestamp. 4808c2ecf20Sopenharmony_ci * etime: 4818c2ecf20Sopenharmony_ci * Target location for timestamp taken immediately after 4828c2ecf20Sopenharmony_ci * scanout position query. Can be NULL to skip timestamp. 4838c2ecf20Sopenharmony_ci * mode: 4848c2ecf20Sopenharmony_ci * Current display timings. 4858c2ecf20Sopenharmony_ci * 4868c2ecf20Sopenharmony_ci * Returns vpos as a positive number while in active scanout area. 4878c2ecf20Sopenharmony_ci * Returns vpos as a negative number inside vblank, counting the number 4888c2ecf20Sopenharmony_ci * of scanlines to go until end of vblank, e.g., -1 means "one scanline 4898c2ecf20Sopenharmony_ci * until start of active scanout / end of vblank." 4908c2ecf20Sopenharmony_ci * 4918c2ecf20Sopenharmony_ci * Returns: 4928c2ecf20Sopenharmony_ci * 4938c2ecf20Sopenharmony_ci * True on success, false if a reliable scanout position counter could 4948c2ecf20Sopenharmony_ci * not be read out. 4958c2ecf20Sopenharmony_ci */ 4968c2ecf20Sopenharmony_ci bool (*get_scanout_position)(struct drm_crtc *crtc, 4978c2ecf20Sopenharmony_ci bool in_vblank_irq, int *vpos, int *hpos, 4988c2ecf20Sopenharmony_ci ktime_t *stime, ktime_t *etime, 4998c2ecf20Sopenharmony_ci const struct drm_display_mode *mode); 5008c2ecf20Sopenharmony_ci}; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci/** 5038c2ecf20Sopenharmony_ci * drm_crtc_helper_add - sets the helper vtable for a crtc 5048c2ecf20Sopenharmony_ci * @crtc: DRM CRTC 5058c2ecf20Sopenharmony_ci * @funcs: helper vtable to set for @crtc 5068c2ecf20Sopenharmony_ci */ 5078c2ecf20Sopenharmony_cistatic inline void drm_crtc_helper_add(struct drm_crtc *crtc, 5088c2ecf20Sopenharmony_ci const struct drm_crtc_helper_funcs *funcs) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci crtc->helper_private = funcs; 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci/** 5148c2ecf20Sopenharmony_ci * struct drm_encoder_helper_funcs - helper operations for encoders 5158c2ecf20Sopenharmony_ci * 5168c2ecf20Sopenharmony_ci * These hooks are used by the legacy CRTC helpers, the transitional plane 5178c2ecf20Sopenharmony_ci * helpers and the new atomic modesetting helpers. 5188c2ecf20Sopenharmony_ci */ 5198c2ecf20Sopenharmony_cistruct drm_encoder_helper_funcs { 5208c2ecf20Sopenharmony_ci /** 5218c2ecf20Sopenharmony_ci * @dpms: 5228c2ecf20Sopenharmony_ci * 5238c2ecf20Sopenharmony_ci * Callback to control power levels on the encoder. If the mode passed in 5248c2ecf20Sopenharmony_ci * is unsupported, the provider must use the next lowest power level. 5258c2ecf20Sopenharmony_ci * This is used by the legacy encoder helpers to implement DPMS 5268c2ecf20Sopenharmony_ci * functionality in drm_helper_connector_dpms(). 5278c2ecf20Sopenharmony_ci * 5288c2ecf20Sopenharmony_ci * This callback is also used to disable an encoder by calling it with 5298c2ecf20Sopenharmony_ci * DRM_MODE_DPMS_OFF if the @disable hook isn't used. 5308c2ecf20Sopenharmony_ci * 5318c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 5328c2ecf20Sopenharmony_ci * also support using this hook for enabling and disabling an encoder to 5338c2ecf20Sopenharmony_ci * facilitate transitions to atomic, but it is deprecated. Instead 5348c2ecf20Sopenharmony_ci * @enable and @disable should be used. 5358c2ecf20Sopenharmony_ci */ 5368c2ecf20Sopenharmony_ci void (*dpms)(struct drm_encoder *encoder, int mode); 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci /** 5398c2ecf20Sopenharmony_ci * @mode_valid: 5408c2ecf20Sopenharmony_ci * 5418c2ecf20Sopenharmony_ci * This callback is used to check if a specific mode is valid in this 5428c2ecf20Sopenharmony_ci * encoder. This should be implemented if the encoder has some sort 5438c2ecf20Sopenharmony_ci * of restriction in the modes it can display. For example, a given 5448c2ecf20Sopenharmony_ci * encoder may be responsible to set a clock value. If the clock can 5458c2ecf20Sopenharmony_ci * not produce all the values for the available modes then this callback 5468c2ecf20Sopenharmony_ci * can be used to restrict the number of modes to only the ones that 5478c2ecf20Sopenharmony_ci * can be displayed. 5488c2ecf20Sopenharmony_ci * 5498c2ecf20Sopenharmony_ci * This hook is used by the probe helpers to filter the mode list in 5508c2ecf20Sopenharmony_ci * drm_helper_probe_single_connector_modes(), and it is used by the 5518c2ecf20Sopenharmony_ci * atomic helpers to validate modes supplied by userspace in 5528c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(). 5538c2ecf20Sopenharmony_ci * 5548c2ecf20Sopenharmony_ci * This function is optional. 5558c2ecf20Sopenharmony_ci * 5568c2ecf20Sopenharmony_ci * NOTE: 5578c2ecf20Sopenharmony_ci * 5588c2ecf20Sopenharmony_ci * Since this function is both called from the check phase of an atomic 5598c2ecf20Sopenharmony_ci * commit, and the mode validation in the probe paths it is not allowed 5608c2ecf20Sopenharmony_ci * to look at anything else but the passed-in mode, and validate it 5618c2ecf20Sopenharmony_ci * against configuration-invariant hardward constraints. Any further 5628c2ecf20Sopenharmony_ci * limits which depend upon the configuration can only be checked in 5638c2ecf20Sopenharmony_ci * @mode_fixup or @atomic_check. 5648c2ecf20Sopenharmony_ci * 5658c2ecf20Sopenharmony_ci * RETURNS: 5668c2ecf20Sopenharmony_ci * 5678c2ecf20Sopenharmony_ci * drm_mode_status Enum 5688c2ecf20Sopenharmony_ci */ 5698c2ecf20Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc, 5708c2ecf20Sopenharmony_ci const struct drm_display_mode *mode); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci /** 5738c2ecf20Sopenharmony_ci * @mode_fixup: 5748c2ecf20Sopenharmony_ci * 5758c2ecf20Sopenharmony_ci * This callback is used to validate and adjust a mode. The parameter 5768c2ecf20Sopenharmony_ci * mode is the display mode that should be fed to the next element in 5778c2ecf20Sopenharmony_ci * the display chain, either the final &drm_connector or a &drm_bridge. 5788c2ecf20Sopenharmony_ci * The parameter adjusted_mode is the input mode the encoder requires. It 5798c2ecf20Sopenharmony_ci * can be modified by this callback and does not need to match mode. See 5808c2ecf20Sopenharmony_ci * also &drm_crtc_state.adjusted_mode for more details. 5818c2ecf20Sopenharmony_ci * 5828c2ecf20Sopenharmony_ci * This function is used by both legacy CRTC helpers and atomic helpers. 5838c2ecf20Sopenharmony_ci * This hook is optional. 5848c2ecf20Sopenharmony_ci * 5858c2ecf20Sopenharmony_ci * NOTE: 5868c2ecf20Sopenharmony_ci * 5878c2ecf20Sopenharmony_ci * This function is called in the check phase of atomic modesets, which 5888c2ecf20Sopenharmony_ci * can be aborted for any reason (including on userspace's request to 5898c2ecf20Sopenharmony_ci * just check whether a configuration would be possible). Atomic drivers 5908c2ecf20Sopenharmony_ci * MUST NOT touch any persistent state (hardware or software) or data 5918c2ecf20Sopenharmony_ci * structures except the passed in adjusted_mode parameter. 5928c2ecf20Sopenharmony_ci * 5938c2ecf20Sopenharmony_ci * This is in contrast to the legacy CRTC helpers where this was 5948c2ecf20Sopenharmony_ci * allowed. 5958c2ecf20Sopenharmony_ci * 5968c2ecf20Sopenharmony_ci * Atomic drivers which need to inspect and adjust more state should 5978c2ecf20Sopenharmony_ci * instead use the @atomic_check callback. If @atomic_check is used, 5988c2ecf20Sopenharmony_ci * this hook isn't called since @atomic_check allows a strict superset 5998c2ecf20Sopenharmony_ci * of the functionality of @mode_fixup. 6008c2ecf20Sopenharmony_ci * 6018c2ecf20Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 6028c2ecf20Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 6038c2ecf20Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 6048c2ecf20Sopenharmony_ci * that modes are filtered consistently put any encoder constraints and 6058c2ecf20Sopenharmony_ci * limits checks into @mode_valid. 6068c2ecf20Sopenharmony_ci * 6078c2ecf20Sopenharmony_ci * RETURNS: 6088c2ecf20Sopenharmony_ci * 6098c2ecf20Sopenharmony_ci * True if an acceptable configuration is possible, false if the modeset 6108c2ecf20Sopenharmony_ci * operation should be rejected. 6118c2ecf20Sopenharmony_ci */ 6128c2ecf20Sopenharmony_ci bool (*mode_fixup)(struct drm_encoder *encoder, 6138c2ecf20Sopenharmony_ci const struct drm_display_mode *mode, 6148c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode); 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci /** 6178c2ecf20Sopenharmony_ci * @prepare: 6188c2ecf20Sopenharmony_ci * 6198c2ecf20Sopenharmony_ci * This callback should prepare the encoder for a subsequent modeset, 6208c2ecf20Sopenharmony_ci * which in practice means the driver should disable the encoder if it 6218c2ecf20Sopenharmony_ci * is running. Most drivers ended up implementing this by calling their 6228c2ecf20Sopenharmony_ci * @dpms hook with DRM_MODE_DPMS_OFF. 6238c2ecf20Sopenharmony_ci * 6248c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 6258c2ecf20Sopenharmony_ci * also support using this hook for disabling an encoder to facilitate 6268c2ecf20Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @disable should 6278c2ecf20Sopenharmony_ci * be used. 6288c2ecf20Sopenharmony_ci */ 6298c2ecf20Sopenharmony_ci void (*prepare)(struct drm_encoder *encoder); 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci /** 6328c2ecf20Sopenharmony_ci * @commit: 6338c2ecf20Sopenharmony_ci * 6348c2ecf20Sopenharmony_ci * This callback should commit the new mode on the encoder after a modeset, 6358c2ecf20Sopenharmony_ci * which in practice means the driver should enable the encoder. Most 6368c2ecf20Sopenharmony_ci * drivers ended up implementing this by calling their @dpms hook with 6378c2ecf20Sopenharmony_ci * DRM_MODE_DPMS_ON. 6388c2ecf20Sopenharmony_ci * 6398c2ecf20Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 6408c2ecf20Sopenharmony_ci * also support using this hook for enabling an encoder to facilitate 6418c2ecf20Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @enable should 6428c2ecf20Sopenharmony_ci * be used. 6438c2ecf20Sopenharmony_ci */ 6448c2ecf20Sopenharmony_ci void (*commit)(struct drm_encoder *encoder); 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci /** 6478c2ecf20Sopenharmony_ci * @mode_set: 6488c2ecf20Sopenharmony_ci * 6498c2ecf20Sopenharmony_ci * This callback is used to update the display mode of an encoder. 6508c2ecf20Sopenharmony_ci * 6518c2ecf20Sopenharmony_ci * Note that the display pipe is completely off when this function is 6528c2ecf20Sopenharmony_ci * called. Drivers which need hardware to be running before they program 6538c2ecf20Sopenharmony_ci * the new display mode (because they implement runtime PM) should not 6548c2ecf20Sopenharmony_ci * use this hook, because the helper library calls it only once and not 6558c2ecf20Sopenharmony_ci * every time the display pipeline is suspend using either DPMS or the 6568c2ecf20Sopenharmony_ci * new "ACTIVE" property. Such drivers should instead move all their 6578c2ecf20Sopenharmony_ci * encoder setup into the @enable callback. 6588c2ecf20Sopenharmony_ci * 6598c2ecf20Sopenharmony_ci * This callback is used both by the legacy CRTC helpers and the atomic 6608c2ecf20Sopenharmony_ci * modeset helpers. It is optional in the atomic helpers. 6618c2ecf20Sopenharmony_ci * 6628c2ecf20Sopenharmony_ci * NOTE: 6638c2ecf20Sopenharmony_ci * 6648c2ecf20Sopenharmony_ci * If the driver uses the atomic modeset helpers and needs to inspect 6658c2ecf20Sopenharmony_ci * the connector state or connector display info during mode setting, 6668c2ecf20Sopenharmony_ci * @atomic_mode_set can be used instead. 6678c2ecf20Sopenharmony_ci */ 6688c2ecf20Sopenharmony_ci void (*mode_set)(struct drm_encoder *encoder, 6698c2ecf20Sopenharmony_ci struct drm_display_mode *mode, 6708c2ecf20Sopenharmony_ci struct drm_display_mode *adjusted_mode); 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci /** 6738c2ecf20Sopenharmony_ci * @atomic_mode_set: 6748c2ecf20Sopenharmony_ci * 6758c2ecf20Sopenharmony_ci * This callback is used to update the display mode of an encoder. 6768c2ecf20Sopenharmony_ci * 6778c2ecf20Sopenharmony_ci * Note that the display pipe is completely off when this function is 6788c2ecf20Sopenharmony_ci * called. Drivers which need hardware to be running before they program 6798c2ecf20Sopenharmony_ci * the new display mode (because they implement runtime PM) should not 6808c2ecf20Sopenharmony_ci * use this hook, because the helper library calls it only once and not 6818c2ecf20Sopenharmony_ci * every time the display pipeline is suspended using either DPMS or the 6828c2ecf20Sopenharmony_ci * new "ACTIVE" property. Such drivers should instead move all their 6838c2ecf20Sopenharmony_ci * encoder setup into the @enable callback. 6848c2ecf20Sopenharmony_ci * 6858c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers in place of the 6868c2ecf20Sopenharmony_ci * @mode_set callback, if set by the driver. It is optional and should 6878c2ecf20Sopenharmony_ci * be used instead of @mode_set if the driver needs to inspect the 6888c2ecf20Sopenharmony_ci * connector state or display info, since there is no direct way to 6898c2ecf20Sopenharmony_ci * go from the encoder to the current connector. 6908c2ecf20Sopenharmony_ci */ 6918c2ecf20Sopenharmony_ci void (*atomic_mode_set)(struct drm_encoder *encoder, 6928c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 6938c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state); 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci /** 6968c2ecf20Sopenharmony_ci * @detect: 6978c2ecf20Sopenharmony_ci * 6988c2ecf20Sopenharmony_ci * This callback can be used by drivers who want to do detection on the 6998c2ecf20Sopenharmony_ci * encoder object instead of in connector functions. 7008c2ecf20Sopenharmony_ci * 7018c2ecf20Sopenharmony_ci * It is not used by any helper and therefore has purely driver-specific 7028c2ecf20Sopenharmony_ci * semantics. New drivers shouldn't use this and instead just implement 7038c2ecf20Sopenharmony_ci * their own private callbacks. 7048c2ecf20Sopenharmony_ci * 7058c2ecf20Sopenharmony_ci * FIXME: 7068c2ecf20Sopenharmony_ci * 7078c2ecf20Sopenharmony_ci * This should just be converted into a pile of driver vfuncs. 7088c2ecf20Sopenharmony_ci * Currently radeon, amdgpu and nouveau are using it. 7098c2ecf20Sopenharmony_ci */ 7108c2ecf20Sopenharmony_ci enum drm_connector_status (*detect)(struct drm_encoder *encoder, 7118c2ecf20Sopenharmony_ci struct drm_connector *connector); 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci /** 7148c2ecf20Sopenharmony_ci * @atomic_disable: 7158c2ecf20Sopenharmony_ci * 7168c2ecf20Sopenharmony_ci * This callback should be used to disable the encoder. With the atomic 7178c2ecf20Sopenharmony_ci * drivers it is called before this encoder's CRTC has been shut off 7188c2ecf20Sopenharmony_ci * using their own &drm_crtc_helper_funcs.atomic_disable hook. If that 7198c2ecf20Sopenharmony_ci * sequence is too simple drivers can just add their own driver private 7208c2ecf20Sopenharmony_ci * encoder hooks and call them from CRTC's callback by looping over all 7218c2ecf20Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 7228c2ecf20Sopenharmony_ci * 7238c2ecf20Sopenharmony_ci * This callback is a variant of @disable that provides the atomic state 7248c2ecf20Sopenharmony_ci * to the driver. If @atomic_disable is implemented, @disable is not 7258c2ecf20Sopenharmony_ci * called by the helpers. 7268c2ecf20Sopenharmony_ci * 7278c2ecf20Sopenharmony_ci * This hook is only used by atomic helpers. Atomic drivers don't need 7288c2ecf20Sopenharmony_ci * to implement it if there's no need to disable anything at the encoder 7298c2ecf20Sopenharmony_ci * level. To ensure that runtime PM handling (using either DPMS or the 7308c2ecf20Sopenharmony_ci * new "ACTIVE" property) works @atomic_disable must be the inverse of 7318c2ecf20Sopenharmony_ci * @atomic_enable. 7328c2ecf20Sopenharmony_ci */ 7338c2ecf20Sopenharmony_ci void (*atomic_disable)(struct drm_encoder *encoder, 7348c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci /** 7378c2ecf20Sopenharmony_ci * @atomic_enable: 7388c2ecf20Sopenharmony_ci * 7398c2ecf20Sopenharmony_ci * This callback should be used to enable the encoder. It is called 7408c2ecf20Sopenharmony_ci * after this encoder's CRTC has been enabled using their own 7418c2ecf20Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_enable hook. If that sequence is 7428c2ecf20Sopenharmony_ci * too simple drivers can just add their own driver private encoder 7438c2ecf20Sopenharmony_ci * hooks and call them from CRTC's callback by looping over all encoders 7448c2ecf20Sopenharmony_ci * connected to it using for_each_encoder_on_crtc(). 7458c2ecf20Sopenharmony_ci * 7468c2ecf20Sopenharmony_ci * This callback is a variant of @enable that provides the atomic state 7478c2ecf20Sopenharmony_ci * to the driver. If @atomic_enable is implemented, @enable is not 7488c2ecf20Sopenharmony_ci * called by the helpers. 7498c2ecf20Sopenharmony_ci * 7508c2ecf20Sopenharmony_ci * This hook is only used by atomic helpers, it is the opposite of 7518c2ecf20Sopenharmony_ci * @atomic_disable. Atomic drivers don't need to implement it if there's 7528c2ecf20Sopenharmony_ci * no need to enable anything at the encoder level. To ensure that 7538c2ecf20Sopenharmony_ci * runtime PM handling works @atomic_enable must be the inverse of 7548c2ecf20Sopenharmony_ci * @atomic_disable. 7558c2ecf20Sopenharmony_ci */ 7568c2ecf20Sopenharmony_ci void (*atomic_enable)(struct drm_encoder *encoder, 7578c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci /** 7608c2ecf20Sopenharmony_ci * @disable: 7618c2ecf20Sopenharmony_ci * 7628c2ecf20Sopenharmony_ci * This callback should be used to disable the encoder. With the atomic 7638c2ecf20Sopenharmony_ci * drivers it is called before this encoder's CRTC has been shut off 7648c2ecf20Sopenharmony_ci * using their own &drm_crtc_helper_funcs.disable hook. If that 7658c2ecf20Sopenharmony_ci * sequence is too simple drivers can just add their own driver private 7668c2ecf20Sopenharmony_ci * encoder hooks and call them from CRTC's callback by looping over all 7678c2ecf20Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 7688c2ecf20Sopenharmony_ci * 7698c2ecf20Sopenharmony_ci * This hook is used both by legacy CRTC helpers and atomic helpers. 7708c2ecf20Sopenharmony_ci * Atomic drivers don't need to implement it if there's no need to 7718c2ecf20Sopenharmony_ci * disable anything at the encoder level. To ensure that runtime PM 7728c2ecf20Sopenharmony_ci * handling (using either DPMS or the new "ACTIVE" property) works 7738c2ecf20Sopenharmony_ci * @disable must be the inverse of @enable for atomic drivers. 7748c2ecf20Sopenharmony_ci * 7758c2ecf20Sopenharmony_ci * For atomic drivers also consider @atomic_disable and save yourself 7768c2ecf20Sopenharmony_ci * from having to read the NOTE below! 7778c2ecf20Sopenharmony_ci * 7788c2ecf20Sopenharmony_ci * NOTE: 7798c2ecf20Sopenharmony_ci * 7808c2ecf20Sopenharmony_ci * With legacy CRTC helpers there's a big semantic difference between 7818c2ecf20Sopenharmony_ci * @disable and other hooks (like @prepare or @dpms) used to shut down a 7828c2ecf20Sopenharmony_ci * encoder: @disable is only called when also logically disabling the 7838c2ecf20Sopenharmony_ci * display pipeline and needs to release any resources acquired in 7848c2ecf20Sopenharmony_ci * @mode_set (like shared PLLs, or again release pinned framebuffers). 7858c2ecf20Sopenharmony_ci * 7868c2ecf20Sopenharmony_ci * Therefore @disable must be the inverse of @mode_set plus @commit for 7878c2ecf20Sopenharmony_ci * drivers still using legacy CRTC helpers, which is different from the 7888c2ecf20Sopenharmony_ci * rules under atomic. 7898c2ecf20Sopenharmony_ci */ 7908c2ecf20Sopenharmony_ci void (*disable)(struct drm_encoder *encoder); 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci /** 7938c2ecf20Sopenharmony_ci * @enable: 7948c2ecf20Sopenharmony_ci * 7958c2ecf20Sopenharmony_ci * This callback should be used to enable the encoder. With the atomic 7968c2ecf20Sopenharmony_ci * drivers it is called after this encoder's CRTC has been enabled using 7978c2ecf20Sopenharmony_ci * their own &drm_crtc_helper_funcs.enable hook. If that sequence is 7988c2ecf20Sopenharmony_ci * too simple drivers can just add their own driver private encoder 7998c2ecf20Sopenharmony_ci * hooks and call them from CRTC's callback by looping over all encoders 8008c2ecf20Sopenharmony_ci * connected to it using for_each_encoder_on_crtc(). 8018c2ecf20Sopenharmony_ci * 8028c2ecf20Sopenharmony_ci * This hook is only used by atomic helpers, it is the opposite of 8038c2ecf20Sopenharmony_ci * @disable. Atomic drivers don't need to implement it if there's no 8048c2ecf20Sopenharmony_ci * need to enable anything at the encoder level. To ensure that 8058c2ecf20Sopenharmony_ci * runtime PM handling (using either DPMS or the new "ACTIVE" property) 8068c2ecf20Sopenharmony_ci * works @enable must be the inverse of @disable for atomic drivers. 8078c2ecf20Sopenharmony_ci */ 8088c2ecf20Sopenharmony_ci void (*enable)(struct drm_encoder *encoder); 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci /** 8118c2ecf20Sopenharmony_ci * @atomic_check: 8128c2ecf20Sopenharmony_ci * 8138c2ecf20Sopenharmony_ci * This callback is used to validate encoder state for atomic drivers. 8148c2ecf20Sopenharmony_ci * Since the encoder is the object connecting the CRTC and connector it 8158c2ecf20Sopenharmony_ci * gets passed both states, to be able to validate interactions and 8168c2ecf20Sopenharmony_ci * update the CRTC to match what the encoder needs for the requested 8178c2ecf20Sopenharmony_ci * connector. 8188c2ecf20Sopenharmony_ci * 8198c2ecf20Sopenharmony_ci * Since this provides a strict superset of the functionality of 8208c2ecf20Sopenharmony_ci * @mode_fixup (the requested and adjusted modes are both available 8218c2ecf20Sopenharmony_ci * through the passed in &struct drm_crtc_state) @mode_fixup is not 8228c2ecf20Sopenharmony_ci * called when @atomic_check is implemented. 8238c2ecf20Sopenharmony_ci * 8248c2ecf20Sopenharmony_ci * This function is used by the atomic helpers, but it is optional. 8258c2ecf20Sopenharmony_ci * 8268c2ecf20Sopenharmony_ci * NOTE: 8278c2ecf20Sopenharmony_ci * 8288c2ecf20Sopenharmony_ci * This function is called in the check phase of an atomic update. The 8298c2ecf20Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 8308c2ecf20Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 8318c2ecf20Sopenharmony_ci * update tracking structure. 8328c2ecf20Sopenharmony_ci * 8338c2ecf20Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 8348c2ecf20Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 8358c2ecf20Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 8368c2ecf20Sopenharmony_ci * that modes are filtered consistently put any encoder constraints and 8378c2ecf20Sopenharmony_ci * limits checks into @mode_valid. 8388c2ecf20Sopenharmony_ci * 8398c2ecf20Sopenharmony_ci * RETURNS: 8408c2ecf20Sopenharmony_ci * 8418c2ecf20Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 8428c2ecf20Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 8438c2ecf20Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 8448c2ecf20Sopenharmony_ci * deadlock. 8458c2ecf20Sopenharmony_ci */ 8468c2ecf20Sopenharmony_ci int (*atomic_check)(struct drm_encoder *encoder, 8478c2ecf20Sopenharmony_ci struct drm_crtc_state *crtc_state, 8488c2ecf20Sopenharmony_ci struct drm_connector_state *conn_state); 8498c2ecf20Sopenharmony_ci}; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci/** 8528c2ecf20Sopenharmony_ci * drm_encoder_helper_add - sets the helper vtable for an encoder 8538c2ecf20Sopenharmony_ci * @encoder: DRM encoder 8548c2ecf20Sopenharmony_ci * @funcs: helper vtable to set for @encoder 8558c2ecf20Sopenharmony_ci */ 8568c2ecf20Sopenharmony_cistatic inline void drm_encoder_helper_add(struct drm_encoder *encoder, 8578c2ecf20Sopenharmony_ci const struct drm_encoder_helper_funcs *funcs) 8588c2ecf20Sopenharmony_ci{ 8598c2ecf20Sopenharmony_ci encoder->helper_private = funcs; 8608c2ecf20Sopenharmony_ci} 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci/** 8638c2ecf20Sopenharmony_ci * struct drm_connector_helper_funcs - helper operations for connectors 8648c2ecf20Sopenharmony_ci * 8658c2ecf20Sopenharmony_ci * These functions are used by the atomic and legacy modeset helpers and by the 8668c2ecf20Sopenharmony_ci * probe helpers. 8678c2ecf20Sopenharmony_ci */ 8688c2ecf20Sopenharmony_cistruct drm_connector_helper_funcs { 8698c2ecf20Sopenharmony_ci /** 8708c2ecf20Sopenharmony_ci * @get_modes: 8718c2ecf20Sopenharmony_ci * 8728c2ecf20Sopenharmony_ci * This function should fill in all modes currently valid for the sink 8738c2ecf20Sopenharmony_ci * into the &drm_connector.probed_modes list. It should also update the 8748c2ecf20Sopenharmony_ci * EDID property by calling drm_connector_update_edid_property(). 8758c2ecf20Sopenharmony_ci * 8768c2ecf20Sopenharmony_ci * The usual way to implement this is to cache the EDID retrieved in the 8778c2ecf20Sopenharmony_ci * probe callback somewhere in the driver-private connector structure. 8788c2ecf20Sopenharmony_ci * In this function drivers then parse the modes in the EDID and add 8798c2ecf20Sopenharmony_ci * them by calling drm_add_edid_modes(). But connectors that driver a 8808c2ecf20Sopenharmony_ci * fixed panel can also manually add specific modes using 8818c2ecf20Sopenharmony_ci * drm_mode_probed_add(). Drivers which manually add modes should also 8828c2ecf20Sopenharmony_ci * make sure that the &drm_connector.display_info, 8838c2ecf20Sopenharmony_ci * &drm_connector.width_mm and &drm_connector.height_mm fields are 8848c2ecf20Sopenharmony_ci * filled in. 8858c2ecf20Sopenharmony_ci * 8868c2ecf20Sopenharmony_ci * Virtual drivers that just want some standard VESA mode with a given 8878c2ecf20Sopenharmony_ci * resolution can call drm_add_modes_noedid(), and mark the preferred 8888c2ecf20Sopenharmony_ci * one using drm_set_preferred_mode(). 8898c2ecf20Sopenharmony_ci * 8908c2ecf20Sopenharmony_ci * This function is only called after the @detect hook has indicated 8918c2ecf20Sopenharmony_ci * that a sink is connected and when the EDID isn't overridden through 8928c2ecf20Sopenharmony_ci * sysfs or the kernel commandline. 8938c2ecf20Sopenharmony_ci * 8948c2ecf20Sopenharmony_ci * This callback is used by the probe helpers in e.g. 8958c2ecf20Sopenharmony_ci * drm_helper_probe_single_connector_modes(). 8968c2ecf20Sopenharmony_ci * 8978c2ecf20Sopenharmony_ci * To avoid races with concurrent connector state updates, the helper 8988c2ecf20Sopenharmony_ci * libraries always call this with the &drm_mode_config.connection_mutex 8998c2ecf20Sopenharmony_ci * held. Because of this it's safe to inspect &drm_connector->state. 9008c2ecf20Sopenharmony_ci * 9018c2ecf20Sopenharmony_ci * RETURNS: 9028c2ecf20Sopenharmony_ci * 9038c2ecf20Sopenharmony_ci * The number of modes added by calling drm_mode_probed_add(). 9048c2ecf20Sopenharmony_ci */ 9058c2ecf20Sopenharmony_ci int (*get_modes)(struct drm_connector *connector); 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci /** 9088c2ecf20Sopenharmony_ci * @detect_ctx: 9098c2ecf20Sopenharmony_ci * 9108c2ecf20Sopenharmony_ci * Check to see if anything is attached to the connector. The parameter 9118c2ecf20Sopenharmony_ci * force is set to false whilst polling, true when checking the 9128c2ecf20Sopenharmony_ci * connector due to a user request. force can be used by the driver to 9138c2ecf20Sopenharmony_ci * avoid expensive, destructive operations during automated probing. 9148c2ecf20Sopenharmony_ci * 9158c2ecf20Sopenharmony_ci * This callback is optional, if not implemented the connector will be 9168c2ecf20Sopenharmony_ci * considered as always being attached. 9178c2ecf20Sopenharmony_ci * 9188c2ecf20Sopenharmony_ci * This is the atomic version of &drm_connector_funcs.detect. 9198c2ecf20Sopenharmony_ci * 9208c2ecf20Sopenharmony_ci * To avoid races against concurrent connector state updates, the 9218c2ecf20Sopenharmony_ci * helper libraries always call this with ctx set to a valid context, 9228c2ecf20Sopenharmony_ci * and &drm_mode_config.connection_mutex will always be locked with 9238c2ecf20Sopenharmony_ci * the ctx parameter set to this ctx. This allows taking additional 9248c2ecf20Sopenharmony_ci * locks as required. 9258c2ecf20Sopenharmony_ci * 9268c2ecf20Sopenharmony_ci * RETURNS: 9278c2ecf20Sopenharmony_ci * 9288c2ecf20Sopenharmony_ci * &drm_connector_status indicating the connector's status, 9298c2ecf20Sopenharmony_ci * or the error code returned by drm_modeset_lock(), -EDEADLK. 9308c2ecf20Sopenharmony_ci */ 9318c2ecf20Sopenharmony_ci int (*detect_ctx)(struct drm_connector *connector, 9328c2ecf20Sopenharmony_ci struct drm_modeset_acquire_ctx *ctx, 9338c2ecf20Sopenharmony_ci bool force); 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci /** 9368c2ecf20Sopenharmony_ci * @mode_valid: 9378c2ecf20Sopenharmony_ci * 9388c2ecf20Sopenharmony_ci * Callback to validate a mode for a connector, irrespective of the 9398c2ecf20Sopenharmony_ci * specific display configuration. 9408c2ecf20Sopenharmony_ci * 9418c2ecf20Sopenharmony_ci * This callback is used by the probe helpers to filter the mode list 9428c2ecf20Sopenharmony_ci * (which is usually derived from the EDID data block from the sink). 9438c2ecf20Sopenharmony_ci * See e.g. drm_helper_probe_single_connector_modes(). 9448c2ecf20Sopenharmony_ci * 9458c2ecf20Sopenharmony_ci * This function is optional. 9468c2ecf20Sopenharmony_ci * 9478c2ecf20Sopenharmony_ci * NOTE: 9488c2ecf20Sopenharmony_ci * 9498c2ecf20Sopenharmony_ci * This only filters the mode list supplied to userspace in the 9508c2ecf20Sopenharmony_ci * GETCONNECTOR IOCTL. Compared to &drm_encoder_helper_funcs.mode_valid, 9518c2ecf20Sopenharmony_ci * &drm_crtc_helper_funcs.mode_valid and &drm_bridge_funcs.mode_valid, 9528c2ecf20Sopenharmony_ci * which are also called by the atomic helpers from 9538c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset(). This allows userspace to force and 9548c2ecf20Sopenharmony_ci * ignore sink constraint (like the pixel clock limits in the screen's 9558c2ecf20Sopenharmony_ci * EDID), which is useful for e.g. testing, or working around a broken 9568c2ecf20Sopenharmony_ci * EDID. Any source hardware constraint (which always need to be 9578c2ecf20Sopenharmony_ci * enforced) therefore should be checked in one of the above callbacks, 9588c2ecf20Sopenharmony_ci * and not this one here. 9598c2ecf20Sopenharmony_ci * 9608c2ecf20Sopenharmony_ci * To avoid races with concurrent connector state updates, the helper 9618c2ecf20Sopenharmony_ci * libraries always call this with the &drm_mode_config.connection_mutex 9628c2ecf20Sopenharmony_ci * held. Because of this it's safe to inspect &drm_connector->state. 9638c2ecf20Sopenharmony_ci * 9648c2ecf20Sopenharmony_ci * RETURNS: 9658c2ecf20Sopenharmony_ci * 9668c2ecf20Sopenharmony_ci * Either &drm_mode_status.MODE_OK or one of the failure reasons in &enum 9678c2ecf20Sopenharmony_ci * drm_mode_status. 9688c2ecf20Sopenharmony_ci */ 9698c2ecf20Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_connector *connector, 9708c2ecf20Sopenharmony_ci struct drm_display_mode *mode); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci /** 9738c2ecf20Sopenharmony_ci * @mode_valid_ctx: 9748c2ecf20Sopenharmony_ci * 9758c2ecf20Sopenharmony_ci * Callback to validate a mode for a connector, irrespective of the 9768c2ecf20Sopenharmony_ci * specific display configuration. 9778c2ecf20Sopenharmony_ci * 9788c2ecf20Sopenharmony_ci * This callback is used by the probe helpers to filter the mode list 9798c2ecf20Sopenharmony_ci * (which is usually derived from the EDID data block from the sink). 9808c2ecf20Sopenharmony_ci * See e.g. drm_helper_probe_single_connector_modes(). 9818c2ecf20Sopenharmony_ci * 9828c2ecf20Sopenharmony_ci * This function is optional, and is the atomic version of 9838c2ecf20Sopenharmony_ci * &drm_connector_helper_funcs.mode_valid. 9848c2ecf20Sopenharmony_ci * 9858c2ecf20Sopenharmony_ci * To allow for accessing the atomic state of modesetting objects, the 9868c2ecf20Sopenharmony_ci * helper libraries always call this with ctx set to a valid context, 9878c2ecf20Sopenharmony_ci * and &drm_mode_config.connection_mutex will always be locked with 9888c2ecf20Sopenharmony_ci * the ctx parameter set to @ctx. This allows for taking additional 9898c2ecf20Sopenharmony_ci * locks as required. 9908c2ecf20Sopenharmony_ci * 9918c2ecf20Sopenharmony_ci * Even though additional locks may be acquired, this callback is 9928c2ecf20Sopenharmony_ci * still expected not to take any constraints into account which would 9938c2ecf20Sopenharmony_ci * be influenced by the currently set display state - such constraints 9948c2ecf20Sopenharmony_ci * should be handled in the driver's atomic check. For example, if a 9958c2ecf20Sopenharmony_ci * connector shares display bandwidth with other connectors then it 9968c2ecf20Sopenharmony_ci * would be ok to validate the minimum bandwidth requirement of a mode 9978c2ecf20Sopenharmony_ci * against the maximum possible bandwidth of the connector. But it 9988c2ecf20Sopenharmony_ci * wouldn't be ok to take the current bandwidth usage of other 9998c2ecf20Sopenharmony_ci * connectors into account, as this would change depending on the 10008c2ecf20Sopenharmony_ci * display state. 10018c2ecf20Sopenharmony_ci * 10028c2ecf20Sopenharmony_ci * Returns: 10038c2ecf20Sopenharmony_ci * 0 if &drm_connector_helper_funcs.mode_valid_ctx succeeded and wrote 10048c2ecf20Sopenharmony_ci * the &enum drm_mode_status value to @status, or a negative error 10058c2ecf20Sopenharmony_ci * code otherwise. 10068c2ecf20Sopenharmony_ci * 10078c2ecf20Sopenharmony_ci */ 10088c2ecf20Sopenharmony_ci int (*mode_valid_ctx)(struct drm_connector *connector, 10098c2ecf20Sopenharmony_ci struct drm_display_mode *mode, 10108c2ecf20Sopenharmony_ci struct drm_modeset_acquire_ctx *ctx, 10118c2ecf20Sopenharmony_ci enum drm_mode_status *status); 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci /** 10148c2ecf20Sopenharmony_ci * @best_encoder: 10158c2ecf20Sopenharmony_ci * 10168c2ecf20Sopenharmony_ci * This function should select the best encoder for the given connector. 10178c2ecf20Sopenharmony_ci * 10188c2ecf20Sopenharmony_ci * This function is used by both the atomic helpers (in the 10198c2ecf20Sopenharmony_ci * drm_atomic_helper_check_modeset() function) and in the legacy CRTC 10208c2ecf20Sopenharmony_ci * helpers. 10218c2ecf20Sopenharmony_ci * 10228c2ecf20Sopenharmony_ci * NOTE: 10238c2ecf20Sopenharmony_ci * 10248c2ecf20Sopenharmony_ci * In atomic drivers this function is called in the check phase of an 10258c2ecf20Sopenharmony_ci * atomic update. The driver is not allowed to change or inspect 10268c2ecf20Sopenharmony_ci * anything outside of arguments passed-in. Atomic drivers which need to 10278c2ecf20Sopenharmony_ci * inspect dynamic configuration state should instead use 10288c2ecf20Sopenharmony_ci * @atomic_best_encoder. 10298c2ecf20Sopenharmony_ci * 10308c2ecf20Sopenharmony_ci * You can leave this function to NULL if the connector is only 10318c2ecf20Sopenharmony_ci * attached to a single encoder. In this case, the core will call 10328c2ecf20Sopenharmony_ci * drm_connector_get_single_encoder() for you. 10338c2ecf20Sopenharmony_ci * 10348c2ecf20Sopenharmony_ci * RETURNS: 10358c2ecf20Sopenharmony_ci * 10368c2ecf20Sopenharmony_ci * Encoder that should be used for the given connector and connector 10378c2ecf20Sopenharmony_ci * state, or NULL if no suitable encoder exists. Note that the helpers 10388c2ecf20Sopenharmony_ci * will ensure that encoders aren't used twice, drivers should not check 10398c2ecf20Sopenharmony_ci * for this. 10408c2ecf20Sopenharmony_ci */ 10418c2ecf20Sopenharmony_ci struct drm_encoder *(*best_encoder)(struct drm_connector *connector); 10428c2ecf20Sopenharmony_ci 10438c2ecf20Sopenharmony_ci /** 10448c2ecf20Sopenharmony_ci * @atomic_best_encoder: 10458c2ecf20Sopenharmony_ci * 10468c2ecf20Sopenharmony_ci * This is the atomic version of @best_encoder for atomic drivers which 10478c2ecf20Sopenharmony_ci * need to select the best encoder depending upon the desired 10488c2ecf20Sopenharmony_ci * configuration and can't select it statically. 10498c2ecf20Sopenharmony_ci * 10508c2ecf20Sopenharmony_ci * This function is used by drm_atomic_helper_check_modeset(). 10518c2ecf20Sopenharmony_ci * If it is not implemented, the core will fallback to @best_encoder 10528c2ecf20Sopenharmony_ci * (or drm_connector_get_single_encoder() if @best_encoder is NULL). 10538c2ecf20Sopenharmony_ci * 10548c2ecf20Sopenharmony_ci * NOTE: 10558c2ecf20Sopenharmony_ci * 10568c2ecf20Sopenharmony_ci * This function is called in the check phase of an atomic update. The 10578c2ecf20Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 10588c2ecf20Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 10598c2ecf20Sopenharmony_ci * update tracking structure. 10608c2ecf20Sopenharmony_ci * 10618c2ecf20Sopenharmony_ci * RETURNS: 10628c2ecf20Sopenharmony_ci * 10638c2ecf20Sopenharmony_ci * Encoder that should be used for the given connector and connector 10648c2ecf20Sopenharmony_ci * state, or NULL if no suitable encoder exists. Note that the helpers 10658c2ecf20Sopenharmony_ci * will ensure that encoders aren't used twice, drivers should not check 10668c2ecf20Sopenharmony_ci * for this. 10678c2ecf20Sopenharmony_ci */ 10688c2ecf20Sopenharmony_ci struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, 10698c2ecf20Sopenharmony_ci struct drm_connector_state *connector_state); 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci /** 10728c2ecf20Sopenharmony_ci * @atomic_check: 10738c2ecf20Sopenharmony_ci * 10748c2ecf20Sopenharmony_ci * This hook is used to validate connector state. This function is 10758c2ecf20Sopenharmony_ci * called from &drm_atomic_helper_check_modeset, and is called when 10768c2ecf20Sopenharmony_ci * a connector property is set, or a modeset on the crtc is forced. 10778c2ecf20Sopenharmony_ci * 10788c2ecf20Sopenharmony_ci * Because &drm_atomic_helper_check_modeset may be called multiple times, 10798c2ecf20Sopenharmony_ci * this function should handle being called multiple times as well. 10808c2ecf20Sopenharmony_ci * 10818c2ecf20Sopenharmony_ci * This function is also allowed to inspect any other object's state and 10828c2ecf20Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 10838c2ecf20Sopenharmony_ci * be taken though to ensure that state check and compute functions for 10848c2ecf20Sopenharmony_ci * these added states are all called, and derived state in other objects 10858c2ecf20Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 10868c2ecf20Sopenharmony_ci * until a maximal configuration is reached. 10878c2ecf20Sopenharmony_ci * 10888c2ecf20Sopenharmony_ci * NOTE: 10898c2ecf20Sopenharmony_ci * 10908c2ecf20Sopenharmony_ci * This function is called in the check phase of an atomic update. The 10918c2ecf20Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 10928c2ecf20Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 10938c2ecf20Sopenharmony_ci * update tracking structure. 10948c2ecf20Sopenharmony_ci * 10958c2ecf20Sopenharmony_ci * RETURNS: 10968c2ecf20Sopenharmony_ci * 10978c2ecf20Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 10988c2ecf20Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 10998c2ecf20Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 11008c2ecf20Sopenharmony_ci * deadlock. 11018c2ecf20Sopenharmony_ci */ 11028c2ecf20Sopenharmony_ci int (*atomic_check)(struct drm_connector *connector, 11038c2ecf20Sopenharmony_ci struct drm_atomic_state *state); 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci /** 11068c2ecf20Sopenharmony_ci * @atomic_commit: 11078c2ecf20Sopenharmony_ci * 11088c2ecf20Sopenharmony_ci * This hook is to be used by drivers implementing writeback connectors 11098c2ecf20Sopenharmony_ci * that need a point when to commit the writeback job to the hardware. 11108c2ecf20Sopenharmony_ci * The writeback_job to commit is available in 11118c2ecf20Sopenharmony_ci * &drm_connector_state.writeback_job. 11128c2ecf20Sopenharmony_ci * 11138c2ecf20Sopenharmony_ci * This hook is optional. 11148c2ecf20Sopenharmony_ci * 11158c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers. 11168c2ecf20Sopenharmony_ci */ 11178c2ecf20Sopenharmony_ci void (*atomic_commit)(struct drm_connector *connector, 11188c2ecf20Sopenharmony_ci struct drm_connector_state *state); 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ci /** 11218c2ecf20Sopenharmony_ci * @prepare_writeback_job: 11228c2ecf20Sopenharmony_ci * 11238c2ecf20Sopenharmony_ci * As writeback jobs contain a framebuffer, drivers may need to 11248c2ecf20Sopenharmony_ci * prepare and clean them up the same way they can prepare and 11258c2ecf20Sopenharmony_ci * clean up framebuffers for planes. This optional connector operation 11268c2ecf20Sopenharmony_ci * is used to support the preparation of writeback jobs. The job 11278c2ecf20Sopenharmony_ci * prepare operation is called from drm_atomic_helper_prepare_planes() 11288c2ecf20Sopenharmony_ci * for struct &drm_writeback_connector connectors only. 11298c2ecf20Sopenharmony_ci * 11308c2ecf20Sopenharmony_ci * This operation is optional. 11318c2ecf20Sopenharmony_ci * 11328c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers. 11338c2ecf20Sopenharmony_ci */ 11348c2ecf20Sopenharmony_ci int (*prepare_writeback_job)(struct drm_writeback_connector *connector, 11358c2ecf20Sopenharmony_ci struct drm_writeback_job *job); 11368c2ecf20Sopenharmony_ci /** 11378c2ecf20Sopenharmony_ci * @cleanup_writeback_job: 11388c2ecf20Sopenharmony_ci * 11398c2ecf20Sopenharmony_ci * This optional connector operation is used to support the 11408c2ecf20Sopenharmony_ci * cleanup of writeback jobs. The job cleanup operation is called 11418c2ecf20Sopenharmony_ci * from the existing drm_writeback_cleanup_job() function, invoked 11428c2ecf20Sopenharmony_ci * both when destroying the job as part of an aborted commit, or when 11438c2ecf20Sopenharmony_ci * the job completes. 11448c2ecf20Sopenharmony_ci * 11458c2ecf20Sopenharmony_ci * This operation is optional. 11468c2ecf20Sopenharmony_ci * 11478c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers. 11488c2ecf20Sopenharmony_ci */ 11498c2ecf20Sopenharmony_ci void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, 11508c2ecf20Sopenharmony_ci struct drm_writeback_job *job); 11518c2ecf20Sopenharmony_ci}; 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_ci/** 11548c2ecf20Sopenharmony_ci * drm_connector_helper_add - sets the helper vtable for a connector 11558c2ecf20Sopenharmony_ci * @connector: DRM connector 11568c2ecf20Sopenharmony_ci * @funcs: helper vtable to set for @connector 11578c2ecf20Sopenharmony_ci */ 11588c2ecf20Sopenharmony_cistatic inline void drm_connector_helper_add(struct drm_connector *connector, 11598c2ecf20Sopenharmony_ci const struct drm_connector_helper_funcs *funcs) 11608c2ecf20Sopenharmony_ci{ 11618c2ecf20Sopenharmony_ci connector->helper_private = funcs; 11628c2ecf20Sopenharmony_ci} 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci/** 11658c2ecf20Sopenharmony_ci * struct drm_plane_helper_funcs - helper operations for planes 11668c2ecf20Sopenharmony_ci * 11678c2ecf20Sopenharmony_ci * These functions are used by the atomic helpers and by the transitional plane 11688c2ecf20Sopenharmony_ci * helpers. 11698c2ecf20Sopenharmony_ci */ 11708c2ecf20Sopenharmony_cistruct drm_plane_helper_funcs { 11718c2ecf20Sopenharmony_ci /** 11728c2ecf20Sopenharmony_ci * @prepare_fb: 11738c2ecf20Sopenharmony_ci * 11748c2ecf20Sopenharmony_ci * This hook is to prepare a framebuffer for scanout by e.g. pinning 11758c2ecf20Sopenharmony_ci * its backing storage or relocating it into a contiguous block of 11768c2ecf20Sopenharmony_ci * VRAM. Other possible preparatory work includes flushing caches. 11778c2ecf20Sopenharmony_ci * 11788c2ecf20Sopenharmony_ci * This function must not block for outstanding rendering, since it is 11798c2ecf20Sopenharmony_ci * called in the context of the atomic IOCTL even for async commits to 11808c2ecf20Sopenharmony_ci * be able to return any errors to userspace. Instead the recommended 11818c2ecf20Sopenharmony_ci * way is to fill out the &drm_plane_state.fence of the passed-in 11828c2ecf20Sopenharmony_ci * &drm_plane_state. If the driver doesn't support native fences then 11838c2ecf20Sopenharmony_ci * equivalent functionality should be implemented through private 11848c2ecf20Sopenharmony_ci * members in the plane structure. 11858c2ecf20Sopenharmony_ci * 11868c2ecf20Sopenharmony_ci * Drivers which always have their buffers pinned should use 11878c2ecf20Sopenharmony_ci * drm_gem_fb_prepare_fb() for this hook. 11888c2ecf20Sopenharmony_ci * 11898c2ecf20Sopenharmony_ci * The helpers will call @cleanup_fb with matching arguments for every 11908c2ecf20Sopenharmony_ci * successful call to this hook. 11918c2ecf20Sopenharmony_ci * 11928c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 11938c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 11948c2ecf20Sopenharmony_ci * 11958c2ecf20Sopenharmony_ci * RETURNS: 11968c2ecf20Sopenharmony_ci * 11978c2ecf20Sopenharmony_ci * 0 on success or one of the following negative error codes allowed by 11988c2ecf20Sopenharmony_ci * the &drm_mode_config_funcs.atomic_commit vfunc. When using helpers 11998c2ecf20Sopenharmony_ci * this callback is the only one which can fail an atomic commit, 12008c2ecf20Sopenharmony_ci * everything else must complete successfully. 12018c2ecf20Sopenharmony_ci */ 12028c2ecf20Sopenharmony_ci int (*prepare_fb)(struct drm_plane *plane, 12038c2ecf20Sopenharmony_ci struct drm_plane_state *new_state); 12048c2ecf20Sopenharmony_ci /** 12058c2ecf20Sopenharmony_ci * @cleanup_fb: 12068c2ecf20Sopenharmony_ci * 12078c2ecf20Sopenharmony_ci * This hook is called to clean up any resources allocated for the given 12088c2ecf20Sopenharmony_ci * framebuffer and plane configuration in @prepare_fb. 12098c2ecf20Sopenharmony_ci * 12108c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 12118c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 12128c2ecf20Sopenharmony_ci */ 12138c2ecf20Sopenharmony_ci void (*cleanup_fb)(struct drm_plane *plane, 12148c2ecf20Sopenharmony_ci struct drm_plane_state *old_state); 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci /** 12178c2ecf20Sopenharmony_ci * @atomic_check: 12188c2ecf20Sopenharmony_ci * 12198c2ecf20Sopenharmony_ci * Drivers should check plane specific constraints in this hook. 12208c2ecf20Sopenharmony_ci * 12218c2ecf20Sopenharmony_ci * When using drm_atomic_helper_check_planes() plane's @atomic_check 12228c2ecf20Sopenharmony_ci * hooks are called before the ones for CRTCs, which allows drivers to 12238c2ecf20Sopenharmony_ci * request shared resources that the CRTC controls here. For more 12248c2ecf20Sopenharmony_ci * complicated dependencies the driver can call the provided check helpers 12258c2ecf20Sopenharmony_ci * multiple times until the computed state has a final configuration and 12268c2ecf20Sopenharmony_ci * everything has been checked. 12278c2ecf20Sopenharmony_ci * 12288c2ecf20Sopenharmony_ci * This function is also allowed to inspect any other object's state and 12298c2ecf20Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 12308c2ecf20Sopenharmony_ci * be taken though to ensure that state check and compute functions for 12318c2ecf20Sopenharmony_ci * these added states are all called, and derived state in other objects 12328c2ecf20Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 12338c2ecf20Sopenharmony_ci * until a maximal configuration is reached. 12348c2ecf20Sopenharmony_ci * 12358c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 12368c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 12378c2ecf20Sopenharmony_ci * 12388c2ecf20Sopenharmony_ci * NOTE: 12398c2ecf20Sopenharmony_ci * 12408c2ecf20Sopenharmony_ci * This function is called in the check phase of an atomic update. The 12418c2ecf20Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 12428c2ecf20Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 12438c2ecf20Sopenharmony_ci * update tracking structure. 12448c2ecf20Sopenharmony_ci * 12458c2ecf20Sopenharmony_ci * RETURNS: 12468c2ecf20Sopenharmony_ci * 12478c2ecf20Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 12488c2ecf20Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 12498c2ecf20Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 12508c2ecf20Sopenharmony_ci * deadlock. 12518c2ecf20Sopenharmony_ci */ 12528c2ecf20Sopenharmony_ci int (*atomic_check)(struct drm_plane *plane, 12538c2ecf20Sopenharmony_ci struct drm_plane_state *state); 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_ci /** 12568c2ecf20Sopenharmony_ci * @atomic_update: 12578c2ecf20Sopenharmony_ci * 12588c2ecf20Sopenharmony_ci * Drivers should use this function to update the plane state. This 12598c2ecf20Sopenharmony_ci * hook is called in-between the &drm_crtc_helper_funcs.atomic_begin and 12608c2ecf20Sopenharmony_ci * drm_crtc_helper_funcs.atomic_flush callbacks. 12618c2ecf20Sopenharmony_ci * 12628c2ecf20Sopenharmony_ci * Note that the power state of the display pipe when this function is 12638c2ecf20Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 12648c2ecf20Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 12658c2ecf20Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 12668c2ecf20Sopenharmony_ci * 12678c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 12688c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 12698c2ecf20Sopenharmony_ci */ 12708c2ecf20Sopenharmony_ci void (*atomic_update)(struct drm_plane *plane, 12718c2ecf20Sopenharmony_ci struct drm_plane_state *old_state); 12728c2ecf20Sopenharmony_ci /** 12738c2ecf20Sopenharmony_ci * @atomic_disable: 12748c2ecf20Sopenharmony_ci * 12758c2ecf20Sopenharmony_ci * Drivers should use this function to unconditionally disable a plane. 12768c2ecf20Sopenharmony_ci * This hook is called in-between the 12778c2ecf20Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_begin and 12788c2ecf20Sopenharmony_ci * drm_crtc_helper_funcs.atomic_flush callbacks. It is an alternative to 12798c2ecf20Sopenharmony_ci * @atomic_update, which will be called for disabling planes, too, if 12808c2ecf20Sopenharmony_ci * the @atomic_disable hook isn't implemented. 12818c2ecf20Sopenharmony_ci * 12828c2ecf20Sopenharmony_ci * This hook is also useful to disable planes in preparation of a modeset, 12838c2ecf20Sopenharmony_ci * by calling drm_atomic_helper_disable_planes_on_crtc() from the 12848c2ecf20Sopenharmony_ci * &drm_crtc_helper_funcs.disable hook. 12858c2ecf20Sopenharmony_ci * 12868c2ecf20Sopenharmony_ci * Note that the power state of the display pipe when this function is 12878c2ecf20Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 12888c2ecf20Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 12898c2ecf20Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 12908c2ecf20Sopenharmony_ci * 12918c2ecf20Sopenharmony_ci * This callback is used by the atomic modeset helpers and by the 12928c2ecf20Sopenharmony_ci * transitional plane helpers, but it is optional. 12938c2ecf20Sopenharmony_ci */ 12948c2ecf20Sopenharmony_ci void (*atomic_disable)(struct drm_plane *plane, 12958c2ecf20Sopenharmony_ci struct drm_plane_state *old_state); 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci /** 12988c2ecf20Sopenharmony_ci * @atomic_async_check: 12998c2ecf20Sopenharmony_ci * 13008c2ecf20Sopenharmony_ci * Drivers should set this function pointer to check if the plane state 13018c2ecf20Sopenharmony_ci * can be updated in a async fashion. Here async means "not vblank 13028c2ecf20Sopenharmony_ci * synchronized". 13038c2ecf20Sopenharmony_ci * 13048c2ecf20Sopenharmony_ci * This hook is called by drm_atomic_async_check() to establish if a 13058c2ecf20Sopenharmony_ci * given update can be committed asynchronously, that is, if it can 13068c2ecf20Sopenharmony_ci * jump ahead of the state currently queued for update. 13078c2ecf20Sopenharmony_ci * 13088c2ecf20Sopenharmony_ci * RETURNS: 13098c2ecf20Sopenharmony_ci * 13108c2ecf20Sopenharmony_ci * Return 0 on success and any error returned indicates that the update 13118c2ecf20Sopenharmony_ci * can not be applied in asynchronous manner. 13128c2ecf20Sopenharmony_ci */ 13138c2ecf20Sopenharmony_ci int (*atomic_async_check)(struct drm_plane *plane, 13148c2ecf20Sopenharmony_ci struct drm_plane_state *state); 13158c2ecf20Sopenharmony_ci 13168c2ecf20Sopenharmony_ci /** 13178c2ecf20Sopenharmony_ci * @atomic_async_update: 13188c2ecf20Sopenharmony_ci * 13198c2ecf20Sopenharmony_ci * Drivers should set this function pointer to perform asynchronous 13208c2ecf20Sopenharmony_ci * updates of planes, that is, jump ahead of the currently queued 13218c2ecf20Sopenharmony_ci * state and update the plane. Here async means "not vblank 13228c2ecf20Sopenharmony_ci * synchronized". 13238c2ecf20Sopenharmony_ci * 13248c2ecf20Sopenharmony_ci * This hook is called by drm_atomic_helper_async_commit(). 13258c2ecf20Sopenharmony_ci * 13268c2ecf20Sopenharmony_ci * An async update will happen on legacy cursor updates. An async 13278c2ecf20Sopenharmony_ci * update won't happen if there is an outstanding commit modifying 13288c2ecf20Sopenharmony_ci * the same plane. 13298c2ecf20Sopenharmony_ci * 13308c2ecf20Sopenharmony_ci * Note that unlike &drm_plane_helper_funcs.atomic_update this hook 13318c2ecf20Sopenharmony_ci * takes the new &drm_plane_state as parameter. When doing async_update 13328c2ecf20Sopenharmony_ci * drivers shouldn't replace the &drm_plane_state but update the 13338c2ecf20Sopenharmony_ci * current one with the new plane configurations in the new 13348c2ecf20Sopenharmony_ci * plane_state. 13358c2ecf20Sopenharmony_ci * 13368c2ecf20Sopenharmony_ci * Drivers should also swap the framebuffers between current plane 13378c2ecf20Sopenharmony_ci * state (&drm_plane.state) and new_state. 13388c2ecf20Sopenharmony_ci * This is required since cleanup for async commits is performed on 13398c2ecf20Sopenharmony_ci * the new state, rather than old state like for traditional commits. 13408c2ecf20Sopenharmony_ci * Since we want to give up the reference on the current (old) fb 13418c2ecf20Sopenharmony_ci * instead of our brand new one, swap them in the driver during the 13428c2ecf20Sopenharmony_ci * async commit. 13438c2ecf20Sopenharmony_ci * 13448c2ecf20Sopenharmony_ci * FIXME: 13458c2ecf20Sopenharmony_ci * - It only works for single plane updates 13468c2ecf20Sopenharmony_ci * - Async Pageflips are not supported yet 13478c2ecf20Sopenharmony_ci * - Some hw might still scan out the old buffer until the next 13488c2ecf20Sopenharmony_ci * vblank, however we let go of the fb references as soon as 13498c2ecf20Sopenharmony_ci * we run this hook. For now drivers must implement their own workers 13508c2ecf20Sopenharmony_ci * for deferring if needed, until a common solution is created. 13518c2ecf20Sopenharmony_ci */ 13528c2ecf20Sopenharmony_ci void (*atomic_async_update)(struct drm_plane *plane, 13538c2ecf20Sopenharmony_ci struct drm_plane_state *new_state); 13548c2ecf20Sopenharmony_ci}; 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci/** 13578c2ecf20Sopenharmony_ci * drm_plane_helper_add - sets the helper vtable for a plane 13588c2ecf20Sopenharmony_ci * @plane: DRM plane 13598c2ecf20Sopenharmony_ci * @funcs: helper vtable to set for @plane 13608c2ecf20Sopenharmony_ci */ 13618c2ecf20Sopenharmony_cistatic inline void drm_plane_helper_add(struct drm_plane *plane, 13628c2ecf20Sopenharmony_ci const struct drm_plane_helper_funcs *funcs) 13638c2ecf20Sopenharmony_ci{ 13648c2ecf20Sopenharmony_ci plane->helper_private = funcs; 13658c2ecf20Sopenharmony_ci} 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci/** 13688c2ecf20Sopenharmony_ci * struct drm_mode_config_helper_funcs - global modeset helper operations 13698c2ecf20Sopenharmony_ci * 13708c2ecf20Sopenharmony_ci * These helper functions are used by the atomic helpers. 13718c2ecf20Sopenharmony_ci */ 13728c2ecf20Sopenharmony_cistruct drm_mode_config_helper_funcs { 13738c2ecf20Sopenharmony_ci /** 13748c2ecf20Sopenharmony_ci * @atomic_commit_tail: 13758c2ecf20Sopenharmony_ci * 13768c2ecf20Sopenharmony_ci * This hook is used by the default atomic_commit() hook implemented in 13778c2ecf20Sopenharmony_ci * drm_atomic_helper_commit() together with the nonblocking commit 13788c2ecf20Sopenharmony_ci * helpers (see drm_atomic_helper_setup_commit() for a starting point) 13798c2ecf20Sopenharmony_ci * to implement blocking and nonblocking commits easily. It is not used 13808c2ecf20Sopenharmony_ci * by the atomic helpers 13818c2ecf20Sopenharmony_ci * 13828c2ecf20Sopenharmony_ci * This function is called when the new atomic state has already been 13838c2ecf20Sopenharmony_ci * swapped into the various state pointers. The passed in state 13848c2ecf20Sopenharmony_ci * therefore contains copies of the old/previous state. This hook should 13858c2ecf20Sopenharmony_ci * commit the new state into hardware. Note that the helpers have 13868c2ecf20Sopenharmony_ci * already waited for preceeding atomic commits and fences, but drivers 13878c2ecf20Sopenharmony_ci * can add more waiting calls at the start of their implementation, e.g. 13888c2ecf20Sopenharmony_ci * to wait for driver-internal request for implicit syncing, before 13898c2ecf20Sopenharmony_ci * starting to commit the update to the hardware. 13908c2ecf20Sopenharmony_ci * 13918c2ecf20Sopenharmony_ci * After the atomic update is committed to the hardware this hook needs 13928c2ecf20Sopenharmony_ci * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate 13938c2ecf20Sopenharmony_ci * to be executed by the hardware, for example using 13948c2ecf20Sopenharmony_ci * drm_atomic_helper_wait_for_vblanks() or 13958c2ecf20Sopenharmony_ci * drm_atomic_helper_wait_for_flip_done(), and then clean up the old 13968c2ecf20Sopenharmony_ci * framebuffers using drm_atomic_helper_cleanup_planes(). 13978c2ecf20Sopenharmony_ci * 13988c2ecf20Sopenharmony_ci * When disabling a CRTC this hook _must_ stall for the commit to 13998c2ecf20Sopenharmony_ci * complete. Vblank waits don't work on disabled CRTC, hence the core 14008c2ecf20Sopenharmony_ci * can't take care of this. And it also can't rely on the vblank event, 14018c2ecf20Sopenharmony_ci * since that can be signalled already when the screen shows black, 14028c2ecf20Sopenharmony_ci * which can happen much earlier than the last hardware access needed to 14038c2ecf20Sopenharmony_ci * shut off the display pipeline completely. 14048c2ecf20Sopenharmony_ci * 14058c2ecf20Sopenharmony_ci * This hook is optional, the default implementation is 14068c2ecf20Sopenharmony_ci * drm_atomic_helper_commit_tail(). 14078c2ecf20Sopenharmony_ci */ 14088c2ecf20Sopenharmony_ci void (*atomic_commit_tail)(struct drm_atomic_state *state); 14098c2ecf20Sopenharmony_ci}; 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci#endif 1412