162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright © 2006 Keith Packard 362306a36Sopenharmony_ci * Copyright © 2007-2008 Dave Airlie 462306a36Sopenharmony_ci * Copyright © 2007-2008 Intel Corporation 562306a36Sopenharmony_ci * Jesse Barnes <jesse.barnes@intel.com> 662306a36Sopenharmony_ci * Copyright © 2011-2013 Intel Corporation 762306a36Sopenharmony_ci * Copyright © 2015 Intel Corporation 862306a36Sopenharmony_ci * Daniel Vetter <daniel.vetter@ffwll.ch> 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 1162306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 1262306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 1362306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1462306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 1562306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1862306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2162306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2262306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2362306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 2462306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2562306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2662306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#ifndef __DRM_MODESET_HELPER_VTABLES_H__ 3062306a36Sopenharmony_ci#define __DRM_MODESET_HELPER_VTABLES_H__ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#include <drm/drm_crtc.h> 3362306a36Sopenharmony_ci#include <drm/drm_encoder.h> 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/** 3662306a36Sopenharmony_ci * DOC: overview 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * The DRM mode setting helper functions are common code for drivers to use if 3962306a36Sopenharmony_ci * they wish. Drivers are not forced to use this code in their 4062306a36Sopenharmony_ci * implementations but it would be useful if the code they do use at least 4162306a36Sopenharmony_ci * provides a consistent interface and operation to userspace. Therefore it is 4262306a36Sopenharmony_ci * highly recommended to use the provided helpers as much as possible. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * Because there is only one pointer per modeset object to hold a vfunc table 4562306a36Sopenharmony_ci * for helper libraries they are by necessity shared among the different 4662306a36Sopenharmony_ci * helpers. 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * To make this clear all the helper vtables are pulled together in this location here. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistruct drm_writeback_connector; 5262306a36Sopenharmony_cistruct drm_writeback_job; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cienum mode_set_atomic { 5562306a36Sopenharmony_ci LEAVE_ATOMIC_MODE_SET, 5662306a36Sopenharmony_ci ENTER_ATOMIC_MODE_SET, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/** 6062306a36Sopenharmony_ci * struct drm_crtc_helper_funcs - helper operations for CRTCs 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * These hooks are used by the legacy CRTC helpers and the new atomic 6362306a36Sopenharmony_ci * modesetting helpers. 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_cistruct drm_crtc_helper_funcs { 6662306a36Sopenharmony_ci /** 6762306a36Sopenharmony_ci * @dpms: 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * Callback to control power levels on the CRTC. If the mode passed in 7062306a36Sopenharmony_ci * is unsupported, the provider must use the next lowest power level. 7162306a36Sopenharmony_ci * This is used by the legacy CRTC helpers to implement DPMS 7262306a36Sopenharmony_ci * functionality in drm_helper_connector_dpms(). 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * This callback is also used to disable a CRTC by calling it with 7562306a36Sopenharmony_ci * DRM_MODE_DPMS_OFF if the @disable hook isn't used. 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 7862306a36Sopenharmony_ci * also support using this hook for enabling and disabling a CRTC to 7962306a36Sopenharmony_ci * facilitate transitions to atomic, but it is deprecated. Instead 8062306a36Sopenharmony_ci * @atomic_enable and @atomic_disable should be used. 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_ci void (*dpms)(struct drm_crtc *crtc, int mode); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci /** 8562306a36Sopenharmony_ci * @prepare: 8662306a36Sopenharmony_ci * 8762306a36Sopenharmony_ci * This callback should prepare the CRTC for a subsequent modeset, which 8862306a36Sopenharmony_ci * in practice means the driver should disable the CRTC if it is 8962306a36Sopenharmony_ci * running. Most drivers ended up implementing this by calling their 9062306a36Sopenharmony_ci * @dpms hook with DRM_MODE_DPMS_OFF. 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 9362306a36Sopenharmony_ci * also support using this hook for disabling a CRTC to facilitate 9462306a36Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @atomic_disable 9562306a36Sopenharmony_ci * should be used. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_ci void (*prepare)(struct drm_crtc *crtc); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci /** 10062306a36Sopenharmony_ci * @commit: 10162306a36Sopenharmony_ci * 10262306a36Sopenharmony_ci * This callback should commit the new mode on the CRTC after a modeset, 10362306a36Sopenharmony_ci * which in practice means the driver should enable the CRTC. Most 10462306a36Sopenharmony_ci * drivers ended up implementing this by calling their @dpms hook with 10562306a36Sopenharmony_ci * DRM_MODE_DPMS_ON. 10662306a36Sopenharmony_ci * 10762306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 10862306a36Sopenharmony_ci * also support using this hook for enabling a CRTC to facilitate 10962306a36Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @atomic_enable 11062306a36Sopenharmony_ci * should be used. 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci void (*commit)(struct drm_crtc *crtc); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /** 11562306a36Sopenharmony_ci * @mode_valid: 11662306a36Sopenharmony_ci * 11762306a36Sopenharmony_ci * This callback is used to check if a specific mode is valid in this 11862306a36Sopenharmony_ci * crtc. This should be implemented if the crtc has some sort of 11962306a36Sopenharmony_ci * restriction in the modes it can display. For example, a given crtc 12062306a36Sopenharmony_ci * may be responsible to set a clock value. If the clock can not 12162306a36Sopenharmony_ci * produce all the values for the available modes then this callback 12262306a36Sopenharmony_ci * can be used to restrict the number of modes to only the ones that 12362306a36Sopenharmony_ci * can be displayed. 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * This hook is used by the probe helpers to filter the mode list in 12662306a36Sopenharmony_ci * drm_helper_probe_single_connector_modes(), and it is used by the 12762306a36Sopenharmony_ci * atomic helpers to validate modes supplied by userspace in 12862306a36Sopenharmony_ci * drm_atomic_helper_check_modeset(). 12962306a36Sopenharmony_ci * 13062306a36Sopenharmony_ci * This function is optional. 13162306a36Sopenharmony_ci * 13262306a36Sopenharmony_ci * NOTE: 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * Since this function is both called from the check phase of an atomic 13562306a36Sopenharmony_ci * commit, and the mode validation in the probe paths it is not allowed 13662306a36Sopenharmony_ci * to look at anything else but the passed-in mode, and validate it 13762306a36Sopenharmony_ci * against configuration-invariant hardward constraints. Any further 13862306a36Sopenharmony_ci * limits which depend upon the configuration can only be checked in 13962306a36Sopenharmony_ci * @mode_fixup or @atomic_check. 14062306a36Sopenharmony_ci * 14162306a36Sopenharmony_ci * RETURNS: 14262306a36Sopenharmony_ci * 14362306a36Sopenharmony_ci * drm_mode_status Enum 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, 14662306a36Sopenharmony_ci const struct drm_display_mode *mode); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /** 14962306a36Sopenharmony_ci * @mode_fixup: 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * This callback is used to validate a mode. The parameter mode is the 15262306a36Sopenharmony_ci * display mode that userspace requested, adjusted_mode is the mode the 15362306a36Sopenharmony_ci * encoders need to be fed with. Note that this is the inverse semantics 15462306a36Sopenharmony_ci * of the meaning for the &drm_encoder and &drm_bridge_funcs.mode_fixup 15562306a36Sopenharmony_ci * vfunc. If the CRTC cannot support the requested conversion from mode 15662306a36Sopenharmony_ci * to adjusted_mode it should reject the modeset. See also 15762306a36Sopenharmony_ci * &drm_crtc_state.adjusted_mode for more details. 15862306a36Sopenharmony_ci * 15962306a36Sopenharmony_ci * This function is used by both legacy CRTC helpers and atomic helpers. 16062306a36Sopenharmony_ci * With atomic helpers it is optional. 16162306a36Sopenharmony_ci * 16262306a36Sopenharmony_ci * NOTE: 16362306a36Sopenharmony_ci * 16462306a36Sopenharmony_ci * This function is called in the check phase of atomic modesets, which 16562306a36Sopenharmony_ci * can be aborted for any reason (including on userspace's request to 16662306a36Sopenharmony_ci * just check whether a configuration would be possible). Atomic drivers 16762306a36Sopenharmony_ci * MUST NOT touch any persistent state (hardware or software) or data 16862306a36Sopenharmony_ci * structures except the passed in adjusted_mode parameter. 16962306a36Sopenharmony_ci * 17062306a36Sopenharmony_ci * This is in contrast to the legacy CRTC helpers where this was 17162306a36Sopenharmony_ci * allowed. 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * Atomic drivers which need to inspect and adjust more state should 17462306a36Sopenharmony_ci * instead use the @atomic_check callback, but note that they're not 17562306a36Sopenharmony_ci * perfectly equivalent: @mode_valid is called from 17662306a36Sopenharmony_ci * drm_atomic_helper_check_modeset(), but @atomic_check is called from 17762306a36Sopenharmony_ci * drm_atomic_helper_check_planes(), because originally it was meant for 17862306a36Sopenharmony_ci * plane update checks only. 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 18162306a36Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 18262306a36Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 18362306a36Sopenharmony_ci * that modes are filtered consistently put any CRTC constraints and 18462306a36Sopenharmony_ci * limits checks into @mode_valid. 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci * RETURNS: 18762306a36Sopenharmony_ci * 18862306a36Sopenharmony_ci * True if an acceptable configuration is possible, false if the modeset 18962306a36Sopenharmony_ci * operation should be rejected. 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci bool (*mode_fixup)(struct drm_crtc *crtc, 19262306a36Sopenharmony_ci const struct drm_display_mode *mode, 19362306a36Sopenharmony_ci struct drm_display_mode *adjusted_mode); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci /** 19662306a36Sopenharmony_ci * @mode_set: 19762306a36Sopenharmony_ci * 19862306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers to set a new mode, 19962306a36Sopenharmony_ci * position and framebuffer. Since it ties the primary plane to every 20062306a36Sopenharmony_ci * mode change it is incompatible with universal plane support. And 20162306a36Sopenharmony_ci * since it can't update other planes it's incompatible with atomic 20262306a36Sopenharmony_ci * modeset support. 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * This callback is only used by CRTC helpers and deprecated. 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * RETURNS: 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * 0 on success or a negative error code on failure. 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_ci int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, 21162306a36Sopenharmony_ci struct drm_display_mode *adjusted_mode, int x, int y, 21262306a36Sopenharmony_ci struct drm_framebuffer *old_fb); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /** 21562306a36Sopenharmony_ci * @mode_set_nofb: 21662306a36Sopenharmony_ci * 21762306a36Sopenharmony_ci * This callback is used to update the display mode of a CRTC without 21862306a36Sopenharmony_ci * changing anything of the primary plane configuration. This fits the 21962306a36Sopenharmony_ci * requirement of atomic and hence is used by the atomic helpers. 22062306a36Sopenharmony_ci * 22162306a36Sopenharmony_ci * Note that the display pipe is completely off when this function is 22262306a36Sopenharmony_ci * called. Atomic drivers which need hardware to be running before they 22362306a36Sopenharmony_ci * program the new display mode (e.g. because they implement runtime PM) 22462306a36Sopenharmony_ci * should not use this hook. This is because the helper library calls 22562306a36Sopenharmony_ci * this hook only once per mode change and not every time the display 22662306a36Sopenharmony_ci * pipeline is suspended using either DPMS or the new "ACTIVE" property. 22762306a36Sopenharmony_ci * Which means register values set in this callback might get reset when 22862306a36Sopenharmony_ci * the CRTC is suspended, but not restored. Such drivers should instead 22962306a36Sopenharmony_ci * move all their CRTC setup into the @atomic_enable callback. 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci * This callback is optional. 23262306a36Sopenharmony_ci */ 23362306a36Sopenharmony_ci void (*mode_set_nofb)(struct drm_crtc *crtc); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci /** 23662306a36Sopenharmony_ci * @mode_set_base: 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers to set a new 23962306a36Sopenharmony_ci * framebuffer and scanout position. It is optional and used as an 24062306a36Sopenharmony_ci * optimized fast-path instead of a full mode set operation with all the 24162306a36Sopenharmony_ci * resulting flickering. If it is not present 24262306a36Sopenharmony_ci * drm_crtc_helper_set_config() will fall back to a full modeset, using 24362306a36Sopenharmony_ci * the @mode_set callback. Since it can't update other planes it's 24462306a36Sopenharmony_ci * incompatible with atomic modeset support. 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * This callback is only used by the CRTC helpers and deprecated. 24762306a36Sopenharmony_ci * 24862306a36Sopenharmony_ci * RETURNS: 24962306a36Sopenharmony_ci * 25062306a36Sopenharmony_ci * 0 on success or a negative error code on failure. 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, 25362306a36Sopenharmony_ci struct drm_framebuffer *old_fb); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /** 25662306a36Sopenharmony_ci * @mode_set_base_atomic: 25762306a36Sopenharmony_ci * 25862306a36Sopenharmony_ci * This callback is used by the fbdev helpers to set a new framebuffer 25962306a36Sopenharmony_ci * and scanout without sleeping, i.e. from an atomic calling context. It 26062306a36Sopenharmony_ci * is only used to implement kgdb support. 26162306a36Sopenharmony_ci * 26262306a36Sopenharmony_ci * This callback is optional and only needed for kgdb support in the fbdev 26362306a36Sopenharmony_ci * helpers. 26462306a36Sopenharmony_ci * 26562306a36Sopenharmony_ci * RETURNS: 26662306a36Sopenharmony_ci * 26762306a36Sopenharmony_ci * 0 on success or a negative error code on failure. 26862306a36Sopenharmony_ci */ 26962306a36Sopenharmony_ci int (*mode_set_base_atomic)(struct drm_crtc *crtc, 27062306a36Sopenharmony_ci struct drm_framebuffer *fb, int x, int y, 27162306a36Sopenharmony_ci enum mode_set_atomic); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci /** 27462306a36Sopenharmony_ci * @disable: 27562306a36Sopenharmony_ci * 27662306a36Sopenharmony_ci * This callback should be used to disable the CRTC. With the atomic 27762306a36Sopenharmony_ci * drivers it is called after all encoders connected to this CRTC have 27862306a36Sopenharmony_ci * been shut off already using their own 27962306a36Sopenharmony_ci * &drm_encoder_helper_funcs.disable hook. If that sequence is too 28062306a36Sopenharmony_ci * simple drivers can just add their own hooks and call it from this 28162306a36Sopenharmony_ci * CRTC callback here by looping over all encoders connected to it using 28262306a36Sopenharmony_ci * for_each_encoder_on_crtc(). 28362306a36Sopenharmony_ci * 28462306a36Sopenharmony_ci * This hook is used both by legacy CRTC helpers and atomic helpers. 28562306a36Sopenharmony_ci * Atomic drivers don't need to implement it if there's no need to 28662306a36Sopenharmony_ci * disable anything at the CRTC level. To ensure that runtime PM 28762306a36Sopenharmony_ci * handling (using either DPMS or the new "ACTIVE" property) works 28862306a36Sopenharmony_ci * @disable must be the inverse of @atomic_enable for atomic drivers. 28962306a36Sopenharmony_ci * Atomic drivers should consider to use @atomic_disable instead of 29062306a36Sopenharmony_ci * this one. 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci * NOTE: 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * With legacy CRTC helpers there's a big semantic difference between 29562306a36Sopenharmony_ci * @disable and other hooks (like @prepare or @dpms) used to shut down a 29662306a36Sopenharmony_ci * CRTC: @disable is only called when also logically disabling the 29762306a36Sopenharmony_ci * display pipeline and needs to release any resources acquired in 29862306a36Sopenharmony_ci * @mode_set (like shared PLLs, or again release pinned framebuffers). 29962306a36Sopenharmony_ci * 30062306a36Sopenharmony_ci * Therefore @disable must be the inverse of @mode_set plus @commit for 30162306a36Sopenharmony_ci * drivers still using legacy CRTC helpers, which is different from the 30262306a36Sopenharmony_ci * rules under atomic. 30362306a36Sopenharmony_ci */ 30462306a36Sopenharmony_ci void (*disable)(struct drm_crtc *crtc); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci /** 30762306a36Sopenharmony_ci * @atomic_check: 30862306a36Sopenharmony_ci * 30962306a36Sopenharmony_ci * Drivers should check plane-update related CRTC constraints in this 31062306a36Sopenharmony_ci * hook. They can also check mode related limitations but need to be 31162306a36Sopenharmony_ci * aware of the calling order, since this hook is used by 31262306a36Sopenharmony_ci * drm_atomic_helper_check_planes() whereas the preparations needed to 31362306a36Sopenharmony_ci * check output routing and the display mode is done in 31462306a36Sopenharmony_ci * drm_atomic_helper_check_modeset(). Therefore drivers that want to 31562306a36Sopenharmony_ci * check output routing and display mode constraints in this callback 31662306a36Sopenharmony_ci * must ensure that drm_atomic_helper_check_modeset() has been called 31762306a36Sopenharmony_ci * beforehand. This is calling order used by the default helper 31862306a36Sopenharmony_ci * implementation in drm_atomic_helper_check(). 31962306a36Sopenharmony_ci * 32062306a36Sopenharmony_ci * When using drm_atomic_helper_check_planes() this hook is called 32162306a36Sopenharmony_ci * after the &drm_plane_helper_funcs.atomic_check hook for planes, which 32262306a36Sopenharmony_ci * allows drivers to assign shared resources requested by planes in this 32362306a36Sopenharmony_ci * callback here. For more complicated dependencies the driver can call 32462306a36Sopenharmony_ci * the provided check helpers multiple times until the computed state 32562306a36Sopenharmony_ci * has a final configuration and everything has been checked. 32662306a36Sopenharmony_ci * 32762306a36Sopenharmony_ci * This function is also allowed to inspect any other object's state and 32862306a36Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 32962306a36Sopenharmony_ci * be taken though to ensure that state check and compute functions for 33062306a36Sopenharmony_ci * these added states are all called, and derived state in other objects 33162306a36Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 33262306a36Sopenharmony_ci * until a maximal configuration is reached. 33362306a36Sopenharmony_ci * 33462306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 33562306a36Sopenharmony_ci * optional. 33662306a36Sopenharmony_ci * 33762306a36Sopenharmony_ci * NOTE: 33862306a36Sopenharmony_ci * 33962306a36Sopenharmony_ci * This function is called in the check phase of an atomic update. The 34062306a36Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 34162306a36Sopenharmony_ci * state object passed-in. 34262306a36Sopenharmony_ci * 34362306a36Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 34462306a36Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 34562306a36Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 34662306a36Sopenharmony_ci * that modes are filtered consistently put any CRTC constraints and 34762306a36Sopenharmony_ci * limits checks into @mode_valid. 34862306a36Sopenharmony_ci * 34962306a36Sopenharmony_ci * RETURNS: 35062306a36Sopenharmony_ci * 35162306a36Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 35262306a36Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 35362306a36Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 35462306a36Sopenharmony_ci * deadlock. 35562306a36Sopenharmony_ci */ 35662306a36Sopenharmony_ci int (*atomic_check)(struct drm_crtc *crtc, 35762306a36Sopenharmony_ci struct drm_atomic_state *state); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /** 36062306a36Sopenharmony_ci * @atomic_begin: 36162306a36Sopenharmony_ci * 36262306a36Sopenharmony_ci * Drivers should prepare for an atomic update of multiple planes on 36362306a36Sopenharmony_ci * a CRTC in this hook. Depending upon hardware this might be vblank 36462306a36Sopenharmony_ci * evasion, blocking updates by setting bits or doing preparatory work 36562306a36Sopenharmony_ci * for e.g. manual update display. 36662306a36Sopenharmony_ci * 36762306a36Sopenharmony_ci * This hook is called before any plane commit functions are called. 36862306a36Sopenharmony_ci * 36962306a36Sopenharmony_ci * Note that the power state of the display pipe when this function is 37062306a36Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 37162306a36Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 37262306a36Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 37362306a36Sopenharmony_ci * 37462306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 37562306a36Sopenharmony_ci * optional. 37662306a36Sopenharmony_ci */ 37762306a36Sopenharmony_ci void (*atomic_begin)(struct drm_crtc *crtc, 37862306a36Sopenharmony_ci struct drm_atomic_state *state); 37962306a36Sopenharmony_ci /** 38062306a36Sopenharmony_ci * @atomic_flush: 38162306a36Sopenharmony_ci * 38262306a36Sopenharmony_ci * Drivers should finalize an atomic update of multiple planes on 38362306a36Sopenharmony_ci * a CRTC in this hook. Depending upon hardware this might include 38462306a36Sopenharmony_ci * checking that vblank evasion was successful, unblocking updates by 38562306a36Sopenharmony_ci * setting bits or setting the GO bit to flush out all updates. 38662306a36Sopenharmony_ci * 38762306a36Sopenharmony_ci * Simple hardware or hardware with special requirements can commit and 38862306a36Sopenharmony_ci * flush out all updates for all planes from this hook and forgo all the 38962306a36Sopenharmony_ci * other commit hooks for plane updates. 39062306a36Sopenharmony_ci * 39162306a36Sopenharmony_ci * This hook is called after any plane commit functions are called. 39262306a36Sopenharmony_ci * 39362306a36Sopenharmony_ci * Note that the power state of the display pipe when this function is 39462306a36Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 39562306a36Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 39662306a36Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 39762306a36Sopenharmony_ci * 39862306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 39962306a36Sopenharmony_ci * optional. 40062306a36Sopenharmony_ci */ 40162306a36Sopenharmony_ci void (*atomic_flush)(struct drm_crtc *crtc, 40262306a36Sopenharmony_ci struct drm_atomic_state *state); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci /** 40562306a36Sopenharmony_ci * @atomic_enable: 40662306a36Sopenharmony_ci * 40762306a36Sopenharmony_ci * This callback should be used to enable the CRTC. With the atomic 40862306a36Sopenharmony_ci * drivers it is called before all encoders connected to this CRTC are 40962306a36Sopenharmony_ci * enabled through the encoder's own &drm_encoder_helper_funcs.enable 41062306a36Sopenharmony_ci * hook. If that sequence is too simple drivers can just add their own 41162306a36Sopenharmony_ci * hooks and call it from this CRTC callback here by looping over all 41262306a36Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 41362306a36Sopenharmony_ci * 41462306a36Sopenharmony_ci * This hook is used only by atomic helpers, for symmetry with 41562306a36Sopenharmony_ci * @atomic_disable. Atomic drivers don't need to implement it if there's 41662306a36Sopenharmony_ci * no need to enable anything at the CRTC level. To ensure that runtime 41762306a36Sopenharmony_ci * PM handling (using either DPMS or the new "ACTIVE" property) works 41862306a36Sopenharmony_ci * @atomic_enable must be the inverse of @atomic_disable for atomic 41962306a36Sopenharmony_ci * drivers. 42062306a36Sopenharmony_ci * 42162306a36Sopenharmony_ci * This function is optional. 42262306a36Sopenharmony_ci */ 42362306a36Sopenharmony_ci void (*atomic_enable)(struct drm_crtc *crtc, 42462306a36Sopenharmony_ci struct drm_atomic_state *state); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci /** 42762306a36Sopenharmony_ci * @atomic_disable: 42862306a36Sopenharmony_ci * 42962306a36Sopenharmony_ci * This callback should be used to disable the CRTC. With the atomic 43062306a36Sopenharmony_ci * drivers it is called after all encoders connected to this CRTC have 43162306a36Sopenharmony_ci * been shut off already using their own 43262306a36Sopenharmony_ci * &drm_encoder_helper_funcs.disable hook. If that sequence is too 43362306a36Sopenharmony_ci * simple drivers can just add their own hooks and call it from this 43462306a36Sopenharmony_ci * CRTC callback here by looping over all encoders connected to it using 43562306a36Sopenharmony_ci * for_each_encoder_on_crtc(). 43662306a36Sopenharmony_ci * 43762306a36Sopenharmony_ci * This hook is used only by atomic helpers. Atomic drivers don't 43862306a36Sopenharmony_ci * need to implement it if there's no need to disable anything at the 43962306a36Sopenharmony_ci * CRTC level. 44062306a36Sopenharmony_ci * 44162306a36Sopenharmony_ci * This function is optional. 44262306a36Sopenharmony_ci */ 44362306a36Sopenharmony_ci void (*atomic_disable)(struct drm_crtc *crtc, 44462306a36Sopenharmony_ci struct drm_atomic_state *state); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci /** 44762306a36Sopenharmony_ci * @get_scanout_position: 44862306a36Sopenharmony_ci * 44962306a36Sopenharmony_ci * Called by vblank timestamping code. 45062306a36Sopenharmony_ci * 45162306a36Sopenharmony_ci * Returns the current display scanout position from a CRTC and an 45262306a36Sopenharmony_ci * optional accurate ktime_get() timestamp of when the position was 45362306a36Sopenharmony_ci * measured. Note that this is a helper callback which is only used 45462306a36Sopenharmony_ci * if a driver uses drm_crtc_vblank_helper_get_vblank_timestamp() 45562306a36Sopenharmony_ci * for the @drm_crtc_funcs.get_vblank_timestamp callback. 45662306a36Sopenharmony_ci * 45762306a36Sopenharmony_ci * Parameters: 45862306a36Sopenharmony_ci * 45962306a36Sopenharmony_ci * crtc: 46062306a36Sopenharmony_ci * The CRTC. 46162306a36Sopenharmony_ci * in_vblank_irq: 46262306a36Sopenharmony_ci * True when called from drm_crtc_handle_vblank(). Some drivers 46362306a36Sopenharmony_ci * need to apply some workarounds for gpu-specific vblank irq 46462306a36Sopenharmony_ci * quirks if the flag is set. 46562306a36Sopenharmony_ci * vpos: 46662306a36Sopenharmony_ci * Target location for current vertical scanout position. 46762306a36Sopenharmony_ci * hpos: 46862306a36Sopenharmony_ci * Target location for current horizontal scanout position. 46962306a36Sopenharmony_ci * stime: 47062306a36Sopenharmony_ci * Target location for timestamp taken immediately before 47162306a36Sopenharmony_ci * scanout position query. Can be NULL to skip timestamp. 47262306a36Sopenharmony_ci * etime: 47362306a36Sopenharmony_ci * Target location for timestamp taken immediately after 47462306a36Sopenharmony_ci * scanout position query. Can be NULL to skip timestamp. 47562306a36Sopenharmony_ci * mode: 47662306a36Sopenharmony_ci * Current display timings. 47762306a36Sopenharmony_ci * 47862306a36Sopenharmony_ci * Returns vpos as a positive number while in active scanout area. 47962306a36Sopenharmony_ci * Returns vpos as a negative number inside vblank, counting the number 48062306a36Sopenharmony_ci * of scanlines to go until end of vblank, e.g., -1 means "one scanline 48162306a36Sopenharmony_ci * until start of active scanout / end of vblank." 48262306a36Sopenharmony_ci * 48362306a36Sopenharmony_ci * Returns: 48462306a36Sopenharmony_ci * 48562306a36Sopenharmony_ci * True on success, false if a reliable scanout position counter could 48662306a36Sopenharmony_ci * not be read out. 48762306a36Sopenharmony_ci */ 48862306a36Sopenharmony_ci bool (*get_scanout_position)(struct drm_crtc *crtc, 48962306a36Sopenharmony_ci bool in_vblank_irq, int *vpos, int *hpos, 49062306a36Sopenharmony_ci ktime_t *stime, ktime_t *etime, 49162306a36Sopenharmony_ci const struct drm_display_mode *mode); 49262306a36Sopenharmony_ci}; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci/** 49562306a36Sopenharmony_ci * drm_crtc_helper_add - sets the helper vtable for a crtc 49662306a36Sopenharmony_ci * @crtc: DRM CRTC 49762306a36Sopenharmony_ci * @funcs: helper vtable to set for @crtc 49862306a36Sopenharmony_ci */ 49962306a36Sopenharmony_cistatic inline void drm_crtc_helper_add(struct drm_crtc *crtc, 50062306a36Sopenharmony_ci const struct drm_crtc_helper_funcs *funcs) 50162306a36Sopenharmony_ci{ 50262306a36Sopenharmony_ci crtc->helper_private = funcs; 50362306a36Sopenharmony_ci} 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci/** 50662306a36Sopenharmony_ci * struct drm_encoder_helper_funcs - helper operations for encoders 50762306a36Sopenharmony_ci * 50862306a36Sopenharmony_ci * These hooks are used by the legacy CRTC helpers and the new atomic 50962306a36Sopenharmony_ci * modesetting helpers. 51062306a36Sopenharmony_ci */ 51162306a36Sopenharmony_cistruct drm_encoder_helper_funcs { 51262306a36Sopenharmony_ci /** 51362306a36Sopenharmony_ci * @dpms: 51462306a36Sopenharmony_ci * 51562306a36Sopenharmony_ci * Callback to control power levels on the encoder. If the mode passed in 51662306a36Sopenharmony_ci * is unsupported, the provider must use the next lowest power level. 51762306a36Sopenharmony_ci * This is used by the legacy encoder helpers to implement DPMS 51862306a36Sopenharmony_ci * functionality in drm_helper_connector_dpms(). 51962306a36Sopenharmony_ci * 52062306a36Sopenharmony_ci * This callback is also used to disable an encoder by calling it with 52162306a36Sopenharmony_ci * DRM_MODE_DPMS_OFF if the @disable hook isn't used. 52262306a36Sopenharmony_ci * 52362306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 52462306a36Sopenharmony_ci * also support using this hook for enabling and disabling an encoder to 52562306a36Sopenharmony_ci * facilitate transitions to atomic, but it is deprecated. Instead 52662306a36Sopenharmony_ci * @enable and @disable should be used. 52762306a36Sopenharmony_ci */ 52862306a36Sopenharmony_ci void (*dpms)(struct drm_encoder *encoder, int mode); 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /** 53162306a36Sopenharmony_ci * @mode_valid: 53262306a36Sopenharmony_ci * 53362306a36Sopenharmony_ci * This callback is used to check if a specific mode is valid in this 53462306a36Sopenharmony_ci * encoder. This should be implemented if the encoder has some sort 53562306a36Sopenharmony_ci * of restriction in the modes it can display. For example, a given 53662306a36Sopenharmony_ci * encoder may be responsible to set a clock value. If the clock can 53762306a36Sopenharmony_ci * not produce all the values for the available modes then this callback 53862306a36Sopenharmony_ci * can be used to restrict the number of modes to only the ones that 53962306a36Sopenharmony_ci * can be displayed. 54062306a36Sopenharmony_ci * 54162306a36Sopenharmony_ci * This hook is used by the probe helpers to filter the mode list in 54262306a36Sopenharmony_ci * drm_helper_probe_single_connector_modes(), and it is used by the 54362306a36Sopenharmony_ci * atomic helpers to validate modes supplied by userspace in 54462306a36Sopenharmony_ci * drm_atomic_helper_check_modeset(). 54562306a36Sopenharmony_ci * 54662306a36Sopenharmony_ci * This function is optional. 54762306a36Sopenharmony_ci * 54862306a36Sopenharmony_ci * NOTE: 54962306a36Sopenharmony_ci * 55062306a36Sopenharmony_ci * Since this function is both called from the check phase of an atomic 55162306a36Sopenharmony_ci * commit, and the mode validation in the probe paths it is not allowed 55262306a36Sopenharmony_ci * to look at anything else but the passed-in mode, and validate it 55362306a36Sopenharmony_ci * against configuration-invariant hardward constraints. Any further 55462306a36Sopenharmony_ci * limits which depend upon the configuration can only be checked in 55562306a36Sopenharmony_ci * @mode_fixup or @atomic_check. 55662306a36Sopenharmony_ci * 55762306a36Sopenharmony_ci * RETURNS: 55862306a36Sopenharmony_ci * 55962306a36Sopenharmony_ci * drm_mode_status Enum 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc, 56262306a36Sopenharmony_ci const struct drm_display_mode *mode); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci /** 56562306a36Sopenharmony_ci * @mode_fixup: 56662306a36Sopenharmony_ci * 56762306a36Sopenharmony_ci * This callback is used to validate and adjust a mode. The parameter 56862306a36Sopenharmony_ci * mode is the display mode that should be fed to the next element in 56962306a36Sopenharmony_ci * the display chain, either the final &drm_connector or a &drm_bridge. 57062306a36Sopenharmony_ci * The parameter adjusted_mode is the input mode the encoder requires. It 57162306a36Sopenharmony_ci * can be modified by this callback and does not need to match mode. See 57262306a36Sopenharmony_ci * also &drm_crtc_state.adjusted_mode for more details. 57362306a36Sopenharmony_ci * 57462306a36Sopenharmony_ci * This function is used by both legacy CRTC helpers and atomic helpers. 57562306a36Sopenharmony_ci * This hook is optional. 57662306a36Sopenharmony_ci * 57762306a36Sopenharmony_ci * NOTE: 57862306a36Sopenharmony_ci * 57962306a36Sopenharmony_ci * This function is called in the check phase of atomic modesets, which 58062306a36Sopenharmony_ci * can be aborted for any reason (including on userspace's request to 58162306a36Sopenharmony_ci * just check whether a configuration would be possible). Atomic drivers 58262306a36Sopenharmony_ci * MUST NOT touch any persistent state (hardware or software) or data 58362306a36Sopenharmony_ci * structures except the passed in adjusted_mode parameter. 58462306a36Sopenharmony_ci * 58562306a36Sopenharmony_ci * This is in contrast to the legacy CRTC helpers where this was 58662306a36Sopenharmony_ci * allowed. 58762306a36Sopenharmony_ci * 58862306a36Sopenharmony_ci * Atomic drivers which need to inspect and adjust more state should 58962306a36Sopenharmony_ci * instead use the @atomic_check callback. If @atomic_check is used, 59062306a36Sopenharmony_ci * this hook isn't called since @atomic_check allows a strict superset 59162306a36Sopenharmony_ci * of the functionality of @mode_fixup. 59262306a36Sopenharmony_ci * 59362306a36Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 59462306a36Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 59562306a36Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 59662306a36Sopenharmony_ci * that modes are filtered consistently put any encoder constraints and 59762306a36Sopenharmony_ci * limits checks into @mode_valid. 59862306a36Sopenharmony_ci * 59962306a36Sopenharmony_ci * RETURNS: 60062306a36Sopenharmony_ci * 60162306a36Sopenharmony_ci * True if an acceptable configuration is possible, false if the modeset 60262306a36Sopenharmony_ci * operation should be rejected. 60362306a36Sopenharmony_ci */ 60462306a36Sopenharmony_ci bool (*mode_fixup)(struct drm_encoder *encoder, 60562306a36Sopenharmony_ci const struct drm_display_mode *mode, 60662306a36Sopenharmony_ci struct drm_display_mode *adjusted_mode); 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci /** 60962306a36Sopenharmony_ci * @prepare: 61062306a36Sopenharmony_ci * 61162306a36Sopenharmony_ci * This callback should prepare the encoder for a subsequent modeset, 61262306a36Sopenharmony_ci * which in practice means the driver should disable the encoder if it 61362306a36Sopenharmony_ci * is running. Most drivers ended up implementing this by calling their 61462306a36Sopenharmony_ci * @dpms hook with DRM_MODE_DPMS_OFF. 61562306a36Sopenharmony_ci * 61662306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 61762306a36Sopenharmony_ci * also support using this hook for disabling an encoder to facilitate 61862306a36Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @disable should 61962306a36Sopenharmony_ci * be used. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_ci void (*prepare)(struct drm_encoder *encoder); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci /** 62462306a36Sopenharmony_ci * @commit: 62562306a36Sopenharmony_ci * 62662306a36Sopenharmony_ci * This callback should commit the new mode on the encoder after a modeset, 62762306a36Sopenharmony_ci * which in practice means the driver should enable the encoder. Most 62862306a36Sopenharmony_ci * drivers ended up implementing this by calling their @dpms hook with 62962306a36Sopenharmony_ci * DRM_MODE_DPMS_ON. 63062306a36Sopenharmony_ci * 63162306a36Sopenharmony_ci * This callback is used by the legacy CRTC helpers. Atomic helpers 63262306a36Sopenharmony_ci * also support using this hook for enabling an encoder to facilitate 63362306a36Sopenharmony_ci * transitions to atomic, but it is deprecated. Instead @enable should 63462306a36Sopenharmony_ci * be used. 63562306a36Sopenharmony_ci */ 63662306a36Sopenharmony_ci void (*commit)(struct drm_encoder *encoder); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci /** 63962306a36Sopenharmony_ci * @mode_set: 64062306a36Sopenharmony_ci * 64162306a36Sopenharmony_ci * This callback is used to update the display mode of an encoder. 64262306a36Sopenharmony_ci * 64362306a36Sopenharmony_ci * Note that the display pipe is completely off when this function is 64462306a36Sopenharmony_ci * called. Drivers which need hardware to be running before they program 64562306a36Sopenharmony_ci * the new display mode (because they implement runtime PM) should not 64662306a36Sopenharmony_ci * use this hook, because the helper library calls it only once and not 64762306a36Sopenharmony_ci * every time the display pipeline is suspend using either DPMS or the 64862306a36Sopenharmony_ci * new "ACTIVE" property. Such drivers should instead move all their 64962306a36Sopenharmony_ci * encoder setup into the @enable callback. 65062306a36Sopenharmony_ci * 65162306a36Sopenharmony_ci * This callback is used both by the legacy CRTC helpers and the atomic 65262306a36Sopenharmony_ci * modeset helpers. It is optional in the atomic helpers. 65362306a36Sopenharmony_ci * 65462306a36Sopenharmony_ci * NOTE: 65562306a36Sopenharmony_ci * 65662306a36Sopenharmony_ci * If the driver uses the atomic modeset helpers and needs to inspect 65762306a36Sopenharmony_ci * the connector state or connector display info during mode setting, 65862306a36Sopenharmony_ci * @atomic_mode_set can be used instead. 65962306a36Sopenharmony_ci */ 66062306a36Sopenharmony_ci void (*mode_set)(struct drm_encoder *encoder, 66162306a36Sopenharmony_ci struct drm_display_mode *mode, 66262306a36Sopenharmony_ci struct drm_display_mode *adjusted_mode); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /** 66562306a36Sopenharmony_ci * @atomic_mode_set: 66662306a36Sopenharmony_ci * 66762306a36Sopenharmony_ci * This callback is used to update the display mode of an encoder. 66862306a36Sopenharmony_ci * 66962306a36Sopenharmony_ci * Note that the display pipe is completely off when this function is 67062306a36Sopenharmony_ci * called. Drivers which need hardware to be running before they program 67162306a36Sopenharmony_ci * the new display mode (because they implement runtime PM) should not 67262306a36Sopenharmony_ci * use this hook, because the helper library calls it only once and not 67362306a36Sopenharmony_ci * every time the display pipeline is suspended using either DPMS or the 67462306a36Sopenharmony_ci * new "ACTIVE" property. Such drivers should instead move all their 67562306a36Sopenharmony_ci * encoder setup into the @enable callback. 67662306a36Sopenharmony_ci * 67762306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers in place of the 67862306a36Sopenharmony_ci * @mode_set callback, if set by the driver. It is optional and should 67962306a36Sopenharmony_ci * be used instead of @mode_set if the driver needs to inspect the 68062306a36Sopenharmony_ci * connector state or display info, since there is no direct way to 68162306a36Sopenharmony_ci * go from the encoder to the current connector. 68262306a36Sopenharmony_ci */ 68362306a36Sopenharmony_ci void (*atomic_mode_set)(struct drm_encoder *encoder, 68462306a36Sopenharmony_ci struct drm_crtc_state *crtc_state, 68562306a36Sopenharmony_ci struct drm_connector_state *conn_state); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci /** 68862306a36Sopenharmony_ci * @detect: 68962306a36Sopenharmony_ci * 69062306a36Sopenharmony_ci * This callback can be used by drivers who want to do detection on the 69162306a36Sopenharmony_ci * encoder object instead of in connector functions. 69262306a36Sopenharmony_ci * 69362306a36Sopenharmony_ci * It is not used by any helper and therefore has purely driver-specific 69462306a36Sopenharmony_ci * semantics. New drivers shouldn't use this and instead just implement 69562306a36Sopenharmony_ci * their own private callbacks. 69662306a36Sopenharmony_ci * 69762306a36Sopenharmony_ci * FIXME: 69862306a36Sopenharmony_ci * 69962306a36Sopenharmony_ci * This should just be converted into a pile of driver vfuncs. 70062306a36Sopenharmony_ci * Currently radeon, amdgpu and nouveau are using it. 70162306a36Sopenharmony_ci */ 70262306a36Sopenharmony_ci enum drm_connector_status (*detect)(struct drm_encoder *encoder, 70362306a36Sopenharmony_ci struct drm_connector *connector); 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci /** 70662306a36Sopenharmony_ci * @atomic_disable: 70762306a36Sopenharmony_ci * 70862306a36Sopenharmony_ci * This callback should be used to disable the encoder. With the atomic 70962306a36Sopenharmony_ci * drivers it is called before this encoder's CRTC has been shut off 71062306a36Sopenharmony_ci * using their own &drm_crtc_helper_funcs.atomic_disable hook. If that 71162306a36Sopenharmony_ci * sequence is too simple drivers can just add their own driver private 71262306a36Sopenharmony_ci * encoder hooks and call them from CRTC's callback by looping over all 71362306a36Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 71462306a36Sopenharmony_ci * 71562306a36Sopenharmony_ci * This callback is a variant of @disable that provides the atomic state 71662306a36Sopenharmony_ci * to the driver. If @atomic_disable is implemented, @disable is not 71762306a36Sopenharmony_ci * called by the helpers. 71862306a36Sopenharmony_ci * 71962306a36Sopenharmony_ci * This hook is only used by atomic helpers. Atomic drivers don't need 72062306a36Sopenharmony_ci * to implement it if there's no need to disable anything at the encoder 72162306a36Sopenharmony_ci * level. To ensure that runtime PM handling (using either DPMS or the 72262306a36Sopenharmony_ci * new "ACTIVE" property) works @atomic_disable must be the inverse of 72362306a36Sopenharmony_ci * @atomic_enable. 72462306a36Sopenharmony_ci */ 72562306a36Sopenharmony_ci void (*atomic_disable)(struct drm_encoder *encoder, 72662306a36Sopenharmony_ci struct drm_atomic_state *state); 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci /** 72962306a36Sopenharmony_ci * @atomic_enable: 73062306a36Sopenharmony_ci * 73162306a36Sopenharmony_ci * This callback should be used to enable the encoder. It is called 73262306a36Sopenharmony_ci * after this encoder's CRTC has been enabled using their own 73362306a36Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_enable hook. If that sequence is 73462306a36Sopenharmony_ci * too simple drivers can just add their own driver private encoder 73562306a36Sopenharmony_ci * hooks and call them from CRTC's callback by looping over all encoders 73662306a36Sopenharmony_ci * connected to it using for_each_encoder_on_crtc(). 73762306a36Sopenharmony_ci * 73862306a36Sopenharmony_ci * This callback is a variant of @enable that provides the atomic state 73962306a36Sopenharmony_ci * to the driver. If @atomic_enable is implemented, @enable is not 74062306a36Sopenharmony_ci * called by the helpers. 74162306a36Sopenharmony_ci * 74262306a36Sopenharmony_ci * This hook is only used by atomic helpers, it is the opposite of 74362306a36Sopenharmony_ci * @atomic_disable. Atomic drivers don't need to implement it if there's 74462306a36Sopenharmony_ci * no need to enable anything at the encoder level. To ensure that 74562306a36Sopenharmony_ci * runtime PM handling works @atomic_enable must be the inverse of 74662306a36Sopenharmony_ci * @atomic_disable. 74762306a36Sopenharmony_ci */ 74862306a36Sopenharmony_ci void (*atomic_enable)(struct drm_encoder *encoder, 74962306a36Sopenharmony_ci struct drm_atomic_state *state); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci /** 75262306a36Sopenharmony_ci * @disable: 75362306a36Sopenharmony_ci * 75462306a36Sopenharmony_ci * This callback should be used to disable the encoder. With the atomic 75562306a36Sopenharmony_ci * drivers it is called before this encoder's CRTC has been shut off 75662306a36Sopenharmony_ci * using their own &drm_crtc_helper_funcs.disable hook. If that 75762306a36Sopenharmony_ci * sequence is too simple drivers can just add their own driver private 75862306a36Sopenharmony_ci * encoder hooks and call them from CRTC's callback by looping over all 75962306a36Sopenharmony_ci * encoders connected to it using for_each_encoder_on_crtc(). 76062306a36Sopenharmony_ci * 76162306a36Sopenharmony_ci * This hook is used both by legacy CRTC helpers and atomic helpers. 76262306a36Sopenharmony_ci * Atomic drivers don't need to implement it if there's no need to 76362306a36Sopenharmony_ci * disable anything at the encoder level. To ensure that runtime PM 76462306a36Sopenharmony_ci * handling (using either DPMS or the new "ACTIVE" property) works 76562306a36Sopenharmony_ci * @disable must be the inverse of @enable for atomic drivers. 76662306a36Sopenharmony_ci * 76762306a36Sopenharmony_ci * For atomic drivers also consider @atomic_disable and save yourself 76862306a36Sopenharmony_ci * from having to read the NOTE below! 76962306a36Sopenharmony_ci * 77062306a36Sopenharmony_ci * NOTE: 77162306a36Sopenharmony_ci * 77262306a36Sopenharmony_ci * With legacy CRTC helpers there's a big semantic difference between 77362306a36Sopenharmony_ci * @disable and other hooks (like @prepare or @dpms) used to shut down a 77462306a36Sopenharmony_ci * encoder: @disable is only called when also logically disabling the 77562306a36Sopenharmony_ci * display pipeline and needs to release any resources acquired in 77662306a36Sopenharmony_ci * @mode_set (like shared PLLs, or again release pinned framebuffers). 77762306a36Sopenharmony_ci * 77862306a36Sopenharmony_ci * Therefore @disable must be the inverse of @mode_set plus @commit for 77962306a36Sopenharmony_ci * drivers still using legacy CRTC helpers, which is different from the 78062306a36Sopenharmony_ci * rules under atomic. 78162306a36Sopenharmony_ci */ 78262306a36Sopenharmony_ci void (*disable)(struct drm_encoder *encoder); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci /** 78562306a36Sopenharmony_ci * @enable: 78662306a36Sopenharmony_ci * 78762306a36Sopenharmony_ci * This callback should be used to enable the encoder. With the atomic 78862306a36Sopenharmony_ci * drivers it is called after this encoder's CRTC has been enabled using 78962306a36Sopenharmony_ci * their own &drm_crtc_helper_funcs.enable hook. If that sequence is 79062306a36Sopenharmony_ci * too simple drivers can just add their own driver private encoder 79162306a36Sopenharmony_ci * hooks and call them from CRTC's callback by looping over all encoders 79262306a36Sopenharmony_ci * connected to it using for_each_encoder_on_crtc(). 79362306a36Sopenharmony_ci * 79462306a36Sopenharmony_ci * This hook is only used by atomic helpers, it is the opposite of 79562306a36Sopenharmony_ci * @disable. Atomic drivers don't need to implement it if there's no 79662306a36Sopenharmony_ci * need to enable anything at the encoder level. To ensure that 79762306a36Sopenharmony_ci * runtime PM handling (using either DPMS or the new "ACTIVE" property) 79862306a36Sopenharmony_ci * works @enable must be the inverse of @disable for atomic drivers. 79962306a36Sopenharmony_ci */ 80062306a36Sopenharmony_ci void (*enable)(struct drm_encoder *encoder); 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci /** 80362306a36Sopenharmony_ci * @atomic_check: 80462306a36Sopenharmony_ci * 80562306a36Sopenharmony_ci * This callback is used to validate encoder state for atomic drivers. 80662306a36Sopenharmony_ci * Since the encoder is the object connecting the CRTC and connector it 80762306a36Sopenharmony_ci * gets passed both states, to be able to validate interactions and 80862306a36Sopenharmony_ci * update the CRTC to match what the encoder needs for the requested 80962306a36Sopenharmony_ci * connector. 81062306a36Sopenharmony_ci * 81162306a36Sopenharmony_ci * Since this provides a strict superset of the functionality of 81262306a36Sopenharmony_ci * @mode_fixup (the requested and adjusted modes are both available 81362306a36Sopenharmony_ci * through the passed in &struct drm_crtc_state) @mode_fixup is not 81462306a36Sopenharmony_ci * called when @atomic_check is implemented. 81562306a36Sopenharmony_ci * 81662306a36Sopenharmony_ci * This function is used by the atomic helpers, but it is optional. 81762306a36Sopenharmony_ci * 81862306a36Sopenharmony_ci * NOTE: 81962306a36Sopenharmony_ci * 82062306a36Sopenharmony_ci * This function is called in the check phase of an atomic update. The 82162306a36Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 82262306a36Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 82362306a36Sopenharmony_ci * update tracking structure. 82462306a36Sopenharmony_ci * 82562306a36Sopenharmony_ci * Also beware that userspace can request its own custom modes, neither 82662306a36Sopenharmony_ci * core nor helpers filter modes to the list of probe modes reported by 82762306a36Sopenharmony_ci * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure 82862306a36Sopenharmony_ci * that modes are filtered consistently put any encoder constraints and 82962306a36Sopenharmony_ci * limits checks into @mode_valid. 83062306a36Sopenharmony_ci * 83162306a36Sopenharmony_ci * RETURNS: 83262306a36Sopenharmony_ci * 83362306a36Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 83462306a36Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 83562306a36Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 83662306a36Sopenharmony_ci * deadlock. 83762306a36Sopenharmony_ci */ 83862306a36Sopenharmony_ci int (*atomic_check)(struct drm_encoder *encoder, 83962306a36Sopenharmony_ci struct drm_crtc_state *crtc_state, 84062306a36Sopenharmony_ci struct drm_connector_state *conn_state); 84162306a36Sopenharmony_ci}; 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci/** 84462306a36Sopenharmony_ci * drm_encoder_helper_add - sets the helper vtable for an encoder 84562306a36Sopenharmony_ci * @encoder: DRM encoder 84662306a36Sopenharmony_ci * @funcs: helper vtable to set for @encoder 84762306a36Sopenharmony_ci */ 84862306a36Sopenharmony_cistatic inline void drm_encoder_helper_add(struct drm_encoder *encoder, 84962306a36Sopenharmony_ci const struct drm_encoder_helper_funcs *funcs) 85062306a36Sopenharmony_ci{ 85162306a36Sopenharmony_ci encoder->helper_private = funcs; 85262306a36Sopenharmony_ci} 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci/** 85562306a36Sopenharmony_ci * struct drm_connector_helper_funcs - helper operations for connectors 85662306a36Sopenharmony_ci * 85762306a36Sopenharmony_ci * These functions are used by the atomic and legacy modeset helpers and by the 85862306a36Sopenharmony_ci * probe helpers. 85962306a36Sopenharmony_ci */ 86062306a36Sopenharmony_cistruct drm_connector_helper_funcs { 86162306a36Sopenharmony_ci /** 86262306a36Sopenharmony_ci * @get_modes: 86362306a36Sopenharmony_ci * 86462306a36Sopenharmony_ci * This function should fill in all modes currently valid for the sink 86562306a36Sopenharmony_ci * into the &drm_connector.probed_modes list. It should also update the 86662306a36Sopenharmony_ci * EDID property by calling drm_connector_update_edid_property(). 86762306a36Sopenharmony_ci * 86862306a36Sopenharmony_ci * The usual way to implement this is to cache the EDID retrieved in the 86962306a36Sopenharmony_ci * probe callback somewhere in the driver-private connector structure. 87062306a36Sopenharmony_ci * In this function drivers then parse the modes in the EDID and add 87162306a36Sopenharmony_ci * them by calling drm_add_edid_modes(). But connectors that drive a 87262306a36Sopenharmony_ci * fixed panel can also manually add specific modes using 87362306a36Sopenharmony_ci * drm_mode_probed_add(). Drivers which manually add modes should also 87462306a36Sopenharmony_ci * make sure that the &drm_connector.display_info, 87562306a36Sopenharmony_ci * &drm_connector.width_mm and &drm_connector.height_mm fields are 87662306a36Sopenharmony_ci * filled in. 87762306a36Sopenharmony_ci * 87862306a36Sopenharmony_ci * Note that the caller function will automatically add standard VESA 87962306a36Sopenharmony_ci * DMT modes up to 1024x768 if the .get_modes() helper operation returns 88062306a36Sopenharmony_ci * no mode and if the connector status is connector_status_connected or 88162306a36Sopenharmony_ci * connector_status_unknown. There is no need to call 88262306a36Sopenharmony_ci * drm_add_modes_noedid() manually in that case. 88362306a36Sopenharmony_ci * 88462306a36Sopenharmony_ci * Virtual drivers that just want some standard VESA mode with a given 88562306a36Sopenharmony_ci * resolution can call drm_add_modes_noedid(), and mark the preferred 88662306a36Sopenharmony_ci * one using drm_set_preferred_mode(). 88762306a36Sopenharmony_ci * 88862306a36Sopenharmony_ci * This function is only called after the @detect hook has indicated 88962306a36Sopenharmony_ci * that a sink is connected and when the EDID isn't overridden through 89062306a36Sopenharmony_ci * sysfs or the kernel commandline. 89162306a36Sopenharmony_ci * 89262306a36Sopenharmony_ci * This callback is used by the probe helpers in e.g. 89362306a36Sopenharmony_ci * drm_helper_probe_single_connector_modes(). 89462306a36Sopenharmony_ci * 89562306a36Sopenharmony_ci * To avoid races with concurrent connector state updates, the helper 89662306a36Sopenharmony_ci * libraries always call this with the &drm_mode_config.connection_mutex 89762306a36Sopenharmony_ci * held. Because of this it's safe to inspect &drm_connector->state. 89862306a36Sopenharmony_ci * 89962306a36Sopenharmony_ci * RETURNS: 90062306a36Sopenharmony_ci * 90162306a36Sopenharmony_ci * The number of modes added by calling drm_mode_probed_add(). 90262306a36Sopenharmony_ci */ 90362306a36Sopenharmony_ci int (*get_modes)(struct drm_connector *connector); 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci /** 90662306a36Sopenharmony_ci * @detect_ctx: 90762306a36Sopenharmony_ci * 90862306a36Sopenharmony_ci * Check to see if anything is attached to the connector. The parameter 90962306a36Sopenharmony_ci * force is set to false whilst polling, true when checking the 91062306a36Sopenharmony_ci * connector due to a user request. force can be used by the driver to 91162306a36Sopenharmony_ci * avoid expensive, destructive operations during automated probing. 91262306a36Sopenharmony_ci * 91362306a36Sopenharmony_ci * This callback is optional, if not implemented the connector will be 91462306a36Sopenharmony_ci * considered as always being attached. 91562306a36Sopenharmony_ci * 91662306a36Sopenharmony_ci * This is the atomic version of &drm_connector_funcs.detect. 91762306a36Sopenharmony_ci * 91862306a36Sopenharmony_ci * To avoid races against concurrent connector state updates, the 91962306a36Sopenharmony_ci * helper libraries always call this with ctx set to a valid context, 92062306a36Sopenharmony_ci * and &drm_mode_config.connection_mutex will always be locked with 92162306a36Sopenharmony_ci * the ctx parameter set to this ctx. This allows taking additional 92262306a36Sopenharmony_ci * locks as required. 92362306a36Sopenharmony_ci * 92462306a36Sopenharmony_ci * RETURNS: 92562306a36Sopenharmony_ci * 92662306a36Sopenharmony_ci * &drm_connector_status indicating the connector's status, 92762306a36Sopenharmony_ci * or the error code returned by drm_modeset_lock(), -EDEADLK. 92862306a36Sopenharmony_ci */ 92962306a36Sopenharmony_ci int (*detect_ctx)(struct drm_connector *connector, 93062306a36Sopenharmony_ci struct drm_modeset_acquire_ctx *ctx, 93162306a36Sopenharmony_ci bool force); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci /** 93462306a36Sopenharmony_ci * @mode_valid: 93562306a36Sopenharmony_ci * 93662306a36Sopenharmony_ci * Callback to validate a mode for a connector, irrespective of the 93762306a36Sopenharmony_ci * specific display configuration. 93862306a36Sopenharmony_ci * 93962306a36Sopenharmony_ci * This callback is used by the probe helpers to filter the mode list 94062306a36Sopenharmony_ci * (which is usually derived from the EDID data block from the sink). 94162306a36Sopenharmony_ci * See e.g. drm_helper_probe_single_connector_modes(). 94262306a36Sopenharmony_ci * 94362306a36Sopenharmony_ci * This function is optional. 94462306a36Sopenharmony_ci * 94562306a36Sopenharmony_ci * NOTE: 94662306a36Sopenharmony_ci * 94762306a36Sopenharmony_ci * This only filters the mode list supplied to userspace in the 94862306a36Sopenharmony_ci * GETCONNECTOR IOCTL. Compared to &drm_encoder_helper_funcs.mode_valid, 94962306a36Sopenharmony_ci * &drm_crtc_helper_funcs.mode_valid and &drm_bridge_funcs.mode_valid, 95062306a36Sopenharmony_ci * which are also called by the atomic helpers from 95162306a36Sopenharmony_ci * drm_atomic_helper_check_modeset(). This allows userspace to force and 95262306a36Sopenharmony_ci * ignore sink constraint (like the pixel clock limits in the screen's 95362306a36Sopenharmony_ci * EDID), which is useful for e.g. testing, or working around a broken 95462306a36Sopenharmony_ci * EDID. Any source hardware constraint (which always need to be 95562306a36Sopenharmony_ci * enforced) therefore should be checked in one of the above callbacks, 95662306a36Sopenharmony_ci * and not this one here. 95762306a36Sopenharmony_ci * 95862306a36Sopenharmony_ci * To avoid races with concurrent connector state updates, the helper 95962306a36Sopenharmony_ci * libraries always call this with the &drm_mode_config.connection_mutex 96062306a36Sopenharmony_ci * held. Because of this it's safe to inspect &drm_connector->state. 96162306a36Sopenharmony_ci * 96262306a36Sopenharmony_ci * RETURNS: 96362306a36Sopenharmony_ci * 96462306a36Sopenharmony_ci * Either &drm_mode_status.MODE_OK or one of the failure reasons in &enum 96562306a36Sopenharmony_ci * drm_mode_status. 96662306a36Sopenharmony_ci */ 96762306a36Sopenharmony_ci enum drm_mode_status (*mode_valid)(struct drm_connector *connector, 96862306a36Sopenharmony_ci struct drm_display_mode *mode); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci /** 97162306a36Sopenharmony_ci * @mode_valid_ctx: 97262306a36Sopenharmony_ci * 97362306a36Sopenharmony_ci * Callback to validate a mode for a connector, irrespective of the 97462306a36Sopenharmony_ci * specific display configuration. 97562306a36Sopenharmony_ci * 97662306a36Sopenharmony_ci * This callback is used by the probe helpers to filter the mode list 97762306a36Sopenharmony_ci * (which is usually derived from the EDID data block from the sink). 97862306a36Sopenharmony_ci * See e.g. drm_helper_probe_single_connector_modes(). 97962306a36Sopenharmony_ci * 98062306a36Sopenharmony_ci * This function is optional, and is the atomic version of 98162306a36Sopenharmony_ci * &drm_connector_helper_funcs.mode_valid. 98262306a36Sopenharmony_ci * 98362306a36Sopenharmony_ci * To allow for accessing the atomic state of modesetting objects, the 98462306a36Sopenharmony_ci * helper libraries always call this with ctx set to a valid context, 98562306a36Sopenharmony_ci * and &drm_mode_config.connection_mutex will always be locked with 98662306a36Sopenharmony_ci * the ctx parameter set to @ctx. This allows for taking additional 98762306a36Sopenharmony_ci * locks as required. 98862306a36Sopenharmony_ci * 98962306a36Sopenharmony_ci * Even though additional locks may be acquired, this callback is 99062306a36Sopenharmony_ci * still expected not to take any constraints into account which would 99162306a36Sopenharmony_ci * be influenced by the currently set display state - such constraints 99262306a36Sopenharmony_ci * should be handled in the driver's atomic check. For example, if a 99362306a36Sopenharmony_ci * connector shares display bandwidth with other connectors then it 99462306a36Sopenharmony_ci * would be ok to validate the minimum bandwidth requirement of a mode 99562306a36Sopenharmony_ci * against the maximum possible bandwidth of the connector. But it 99662306a36Sopenharmony_ci * wouldn't be ok to take the current bandwidth usage of other 99762306a36Sopenharmony_ci * connectors into account, as this would change depending on the 99862306a36Sopenharmony_ci * display state. 99962306a36Sopenharmony_ci * 100062306a36Sopenharmony_ci * Returns: 100162306a36Sopenharmony_ci * 0 if &drm_connector_helper_funcs.mode_valid_ctx succeeded and wrote 100262306a36Sopenharmony_ci * the &enum drm_mode_status value to @status, or a negative error 100362306a36Sopenharmony_ci * code otherwise. 100462306a36Sopenharmony_ci * 100562306a36Sopenharmony_ci */ 100662306a36Sopenharmony_ci int (*mode_valid_ctx)(struct drm_connector *connector, 100762306a36Sopenharmony_ci struct drm_display_mode *mode, 100862306a36Sopenharmony_ci struct drm_modeset_acquire_ctx *ctx, 100962306a36Sopenharmony_ci enum drm_mode_status *status); 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci /** 101262306a36Sopenharmony_ci * @best_encoder: 101362306a36Sopenharmony_ci * 101462306a36Sopenharmony_ci * This function should select the best encoder for the given connector. 101562306a36Sopenharmony_ci * 101662306a36Sopenharmony_ci * This function is used by both the atomic helpers (in the 101762306a36Sopenharmony_ci * drm_atomic_helper_check_modeset() function) and in the legacy CRTC 101862306a36Sopenharmony_ci * helpers. 101962306a36Sopenharmony_ci * 102062306a36Sopenharmony_ci * NOTE: 102162306a36Sopenharmony_ci * 102262306a36Sopenharmony_ci * In atomic drivers this function is called in the check phase of an 102362306a36Sopenharmony_ci * atomic update. The driver is not allowed to change or inspect 102462306a36Sopenharmony_ci * anything outside of arguments passed-in. Atomic drivers which need to 102562306a36Sopenharmony_ci * inspect dynamic configuration state should instead use 102662306a36Sopenharmony_ci * @atomic_best_encoder. 102762306a36Sopenharmony_ci * 102862306a36Sopenharmony_ci * You can leave this function to NULL if the connector is only 102962306a36Sopenharmony_ci * attached to a single encoder. In this case, the core will call 103062306a36Sopenharmony_ci * drm_connector_get_single_encoder() for you. 103162306a36Sopenharmony_ci * 103262306a36Sopenharmony_ci * RETURNS: 103362306a36Sopenharmony_ci * 103462306a36Sopenharmony_ci * Encoder that should be used for the given connector and connector 103562306a36Sopenharmony_ci * state, or NULL if no suitable encoder exists. Note that the helpers 103662306a36Sopenharmony_ci * will ensure that encoders aren't used twice, drivers should not check 103762306a36Sopenharmony_ci * for this. 103862306a36Sopenharmony_ci */ 103962306a36Sopenharmony_ci struct drm_encoder *(*best_encoder)(struct drm_connector *connector); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci /** 104262306a36Sopenharmony_ci * @atomic_best_encoder: 104362306a36Sopenharmony_ci * 104462306a36Sopenharmony_ci * This is the atomic version of @best_encoder for atomic drivers which 104562306a36Sopenharmony_ci * need to select the best encoder depending upon the desired 104662306a36Sopenharmony_ci * configuration and can't select it statically. 104762306a36Sopenharmony_ci * 104862306a36Sopenharmony_ci * This function is used by drm_atomic_helper_check_modeset(). 104962306a36Sopenharmony_ci * If it is not implemented, the core will fallback to @best_encoder 105062306a36Sopenharmony_ci * (or drm_connector_get_single_encoder() if @best_encoder is NULL). 105162306a36Sopenharmony_ci * 105262306a36Sopenharmony_ci * NOTE: 105362306a36Sopenharmony_ci * 105462306a36Sopenharmony_ci * This function is called in the check phase of an atomic update. The 105562306a36Sopenharmony_ci * driver is not allowed to change anything outside of the 105662306a36Sopenharmony_ci * &drm_atomic_state update tracking structure passed in. 105762306a36Sopenharmony_ci * 105862306a36Sopenharmony_ci * RETURNS: 105962306a36Sopenharmony_ci * 106062306a36Sopenharmony_ci * Encoder that should be used for the given connector and connector 106162306a36Sopenharmony_ci * state, or NULL if no suitable encoder exists. Note that the helpers 106262306a36Sopenharmony_ci * will ensure that encoders aren't used twice, drivers should not check 106362306a36Sopenharmony_ci * for this. 106462306a36Sopenharmony_ci */ 106562306a36Sopenharmony_ci struct drm_encoder *(*atomic_best_encoder)(struct drm_connector *connector, 106662306a36Sopenharmony_ci struct drm_atomic_state *state); 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci /** 106962306a36Sopenharmony_ci * @atomic_check: 107062306a36Sopenharmony_ci * 107162306a36Sopenharmony_ci * This hook is used to validate connector state. This function is 107262306a36Sopenharmony_ci * called from &drm_atomic_helper_check_modeset, and is called when 107362306a36Sopenharmony_ci * a connector property is set, or a modeset on the crtc is forced. 107462306a36Sopenharmony_ci * 107562306a36Sopenharmony_ci * Because &drm_atomic_helper_check_modeset may be called multiple times, 107662306a36Sopenharmony_ci * this function should handle being called multiple times as well. 107762306a36Sopenharmony_ci * 107862306a36Sopenharmony_ci * This function is also allowed to inspect any other object's state and 107962306a36Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 108062306a36Sopenharmony_ci * be taken though to ensure that state check and compute functions for 108162306a36Sopenharmony_ci * these added states are all called, and derived state in other objects 108262306a36Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 108362306a36Sopenharmony_ci * until a maximal configuration is reached. 108462306a36Sopenharmony_ci * 108562306a36Sopenharmony_ci * NOTE: 108662306a36Sopenharmony_ci * 108762306a36Sopenharmony_ci * This function is called in the check phase of an atomic update. The 108862306a36Sopenharmony_ci * driver is not allowed to change anything outside of the free-standing 108962306a36Sopenharmony_ci * state objects passed-in or assembled in the overall &drm_atomic_state 109062306a36Sopenharmony_ci * update tracking structure. 109162306a36Sopenharmony_ci * 109262306a36Sopenharmony_ci * RETURNS: 109362306a36Sopenharmony_ci * 109462306a36Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 109562306a36Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 109662306a36Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 109762306a36Sopenharmony_ci * deadlock. 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ci int (*atomic_check)(struct drm_connector *connector, 110062306a36Sopenharmony_ci struct drm_atomic_state *state); 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci /** 110362306a36Sopenharmony_ci * @atomic_commit: 110462306a36Sopenharmony_ci * 110562306a36Sopenharmony_ci * This hook is to be used by drivers implementing writeback connectors 110662306a36Sopenharmony_ci * that need a point when to commit the writeback job to the hardware. 110762306a36Sopenharmony_ci * The writeback_job to commit is available in the new connector state, 110862306a36Sopenharmony_ci * in &drm_connector_state.writeback_job. 110962306a36Sopenharmony_ci * 111062306a36Sopenharmony_ci * This hook is optional. 111162306a36Sopenharmony_ci * 111262306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers. 111362306a36Sopenharmony_ci */ 111462306a36Sopenharmony_ci void (*atomic_commit)(struct drm_connector *connector, 111562306a36Sopenharmony_ci struct drm_atomic_state *state); 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci /** 111862306a36Sopenharmony_ci * @prepare_writeback_job: 111962306a36Sopenharmony_ci * 112062306a36Sopenharmony_ci * As writeback jobs contain a framebuffer, drivers may need to 112162306a36Sopenharmony_ci * prepare and clean them up the same way they can prepare and 112262306a36Sopenharmony_ci * clean up framebuffers for planes. This optional connector operation 112362306a36Sopenharmony_ci * is used to support the preparation of writeback jobs. The job 112462306a36Sopenharmony_ci * prepare operation is called from drm_atomic_helper_prepare_planes() 112562306a36Sopenharmony_ci * for struct &drm_writeback_connector connectors only. 112662306a36Sopenharmony_ci * 112762306a36Sopenharmony_ci * This operation is optional. 112862306a36Sopenharmony_ci * 112962306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers. 113062306a36Sopenharmony_ci */ 113162306a36Sopenharmony_ci int (*prepare_writeback_job)(struct drm_writeback_connector *connector, 113262306a36Sopenharmony_ci struct drm_writeback_job *job); 113362306a36Sopenharmony_ci /** 113462306a36Sopenharmony_ci * @cleanup_writeback_job: 113562306a36Sopenharmony_ci * 113662306a36Sopenharmony_ci * This optional connector operation is used to support the 113762306a36Sopenharmony_ci * cleanup of writeback jobs. The job cleanup operation is called 113862306a36Sopenharmony_ci * from the existing drm_writeback_cleanup_job() function, invoked 113962306a36Sopenharmony_ci * both when destroying the job as part of an aborted commit, or when 114062306a36Sopenharmony_ci * the job completes. 114162306a36Sopenharmony_ci * 114262306a36Sopenharmony_ci * This operation is optional. 114362306a36Sopenharmony_ci * 114462306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers. 114562306a36Sopenharmony_ci */ 114662306a36Sopenharmony_ci void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, 114762306a36Sopenharmony_ci struct drm_writeback_job *job); 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci /** 115062306a36Sopenharmony_ci * @enable_hpd: 115162306a36Sopenharmony_ci * 115262306a36Sopenharmony_ci * Enable hot-plug detection for the connector. 115362306a36Sopenharmony_ci * 115462306a36Sopenharmony_ci * This operation is optional. 115562306a36Sopenharmony_ci * 115662306a36Sopenharmony_ci * This callback is used by the drm_kms_helper_poll_enable() helpers. 115762306a36Sopenharmony_ci */ 115862306a36Sopenharmony_ci void (*enable_hpd)(struct drm_connector *connector); 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci /** 116162306a36Sopenharmony_ci * @disable_hpd: 116262306a36Sopenharmony_ci * 116362306a36Sopenharmony_ci * Disable hot-plug detection for the connector. 116462306a36Sopenharmony_ci * 116562306a36Sopenharmony_ci * This operation is optional. 116662306a36Sopenharmony_ci * 116762306a36Sopenharmony_ci * This callback is used by the drm_kms_helper_poll_disable() helpers. 116862306a36Sopenharmony_ci */ 116962306a36Sopenharmony_ci void (*disable_hpd)(struct drm_connector *connector); 117062306a36Sopenharmony_ci}; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci/** 117362306a36Sopenharmony_ci * drm_connector_helper_add - sets the helper vtable for a connector 117462306a36Sopenharmony_ci * @connector: DRM connector 117562306a36Sopenharmony_ci * @funcs: helper vtable to set for @connector 117662306a36Sopenharmony_ci */ 117762306a36Sopenharmony_cistatic inline void drm_connector_helper_add(struct drm_connector *connector, 117862306a36Sopenharmony_ci const struct drm_connector_helper_funcs *funcs) 117962306a36Sopenharmony_ci{ 118062306a36Sopenharmony_ci connector->helper_private = funcs; 118162306a36Sopenharmony_ci} 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci/** 118462306a36Sopenharmony_ci * struct drm_plane_helper_funcs - helper operations for planes 118562306a36Sopenharmony_ci * 118662306a36Sopenharmony_ci * These functions are used by the atomic helpers. 118762306a36Sopenharmony_ci */ 118862306a36Sopenharmony_cistruct drm_plane_helper_funcs { 118962306a36Sopenharmony_ci /** 119062306a36Sopenharmony_ci * @prepare_fb: 119162306a36Sopenharmony_ci * 119262306a36Sopenharmony_ci * This hook is to prepare a framebuffer for scanout by e.g. pinning 119362306a36Sopenharmony_ci * its backing storage or relocating it into a contiguous block of 119462306a36Sopenharmony_ci * VRAM. Other possible preparatory work includes flushing caches. 119562306a36Sopenharmony_ci * 119662306a36Sopenharmony_ci * This function must not block for outstanding rendering, since it is 119762306a36Sopenharmony_ci * called in the context of the atomic IOCTL even for async commits to 119862306a36Sopenharmony_ci * be able to return any errors to userspace. Instead the recommended 119962306a36Sopenharmony_ci * way is to fill out the &drm_plane_state.fence of the passed-in 120062306a36Sopenharmony_ci * &drm_plane_state. If the driver doesn't support native fences then 120162306a36Sopenharmony_ci * equivalent functionality should be implemented through private 120262306a36Sopenharmony_ci * members in the plane structure. 120362306a36Sopenharmony_ci * 120462306a36Sopenharmony_ci * For GEM drivers who neither have a @prepare_fb nor @cleanup_fb hook 120562306a36Sopenharmony_ci * set drm_gem_plane_helper_prepare_fb() is called automatically to 120662306a36Sopenharmony_ci * implement this. Other drivers which need additional plane processing 120762306a36Sopenharmony_ci * can call drm_gem_plane_helper_prepare_fb() from their @prepare_fb 120862306a36Sopenharmony_ci * hook. 120962306a36Sopenharmony_ci * 121062306a36Sopenharmony_ci * The resources acquired in @prepare_fb persist after the end of 121162306a36Sopenharmony_ci * the atomic commit. Resources that can be release at the commit's end 121262306a36Sopenharmony_ci * should be acquired in @begin_fb_access and released in @end_fb_access. 121362306a36Sopenharmony_ci * For example, a GEM buffer's pin operation belongs into @prepare_fb to 121462306a36Sopenharmony_ci * keep the buffer pinned after the commit. But a vmap operation for 121562306a36Sopenharmony_ci * shadow-plane helpers belongs into @begin_fb_access, so that atomic 121662306a36Sopenharmony_ci * helpers remove the mapping at the end of the commit. 121762306a36Sopenharmony_ci * 121862306a36Sopenharmony_ci * The helpers will call @cleanup_fb with matching arguments for every 121962306a36Sopenharmony_ci * successful call to this hook. 122062306a36Sopenharmony_ci * 122162306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 122262306a36Sopenharmony_ci * optional. See @begin_fb_access for preparing per-commit resources. 122362306a36Sopenharmony_ci * 122462306a36Sopenharmony_ci * RETURNS: 122562306a36Sopenharmony_ci * 122662306a36Sopenharmony_ci * 0 on success or one of the following negative error codes allowed by 122762306a36Sopenharmony_ci * the &drm_mode_config_funcs.atomic_commit vfunc. When using helpers 122862306a36Sopenharmony_ci * this callback is the only one which can fail an atomic commit, 122962306a36Sopenharmony_ci * everything else must complete successfully. 123062306a36Sopenharmony_ci */ 123162306a36Sopenharmony_ci int (*prepare_fb)(struct drm_plane *plane, 123262306a36Sopenharmony_ci struct drm_plane_state *new_state); 123362306a36Sopenharmony_ci /** 123462306a36Sopenharmony_ci * @cleanup_fb: 123562306a36Sopenharmony_ci * 123662306a36Sopenharmony_ci * This hook is called to clean up any resources allocated for the given 123762306a36Sopenharmony_ci * framebuffer and plane configuration in @prepare_fb. 123862306a36Sopenharmony_ci * 123962306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 124062306a36Sopenharmony_ci * optional. 124162306a36Sopenharmony_ci */ 124262306a36Sopenharmony_ci void (*cleanup_fb)(struct drm_plane *plane, 124362306a36Sopenharmony_ci struct drm_plane_state *old_state); 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci /** 124662306a36Sopenharmony_ci * @begin_fb_access: 124762306a36Sopenharmony_ci * 124862306a36Sopenharmony_ci * This hook prepares the plane for access during an atomic commit. 124962306a36Sopenharmony_ci * In contrast to @prepare_fb, resources acquired in @begin_fb_access, 125062306a36Sopenharmony_ci * are released at the end of the atomic commit in @end_fb_access. 125162306a36Sopenharmony_ci * 125262306a36Sopenharmony_ci * For example, with shadow-plane helpers, the GEM buffer's vmap 125362306a36Sopenharmony_ci * operation belongs into @begin_fb_access, so that the buffer's 125462306a36Sopenharmony_ci * memory will be unmapped at the end of the commit in @end_fb_access. 125562306a36Sopenharmony_ci * But a GEM buffer's pin operation belongs into @prepare_fb 125662306a36Sopenharmony_ci * to keep the buffer pinned after the commit. 125762306a36Sopenharmony_ci * 125862306a36Sopenharmony_ci * The callback is used by the atomic modeset helpers, but it is optional. 125962306a36Sopenharmony_ci * See @end_fb_cleanup for undoing the effects of @begin_fb_access and 126062306a36Sopenharmony_ci * @prepare_fb for acquiring resources until the next pageflip. 126162306a36Sopenharmony_ci * 126262306a36Sopenharmony_ci * Returns: 126362306a36Sopenharmony_ci * 0 on success, or a negative errno code otherwise. 126462306a36Sopenharmony_ci */ 126562306a36Sopenharmony_ci int (*begin_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci /** 126862306a36Sopenharmony_ci * @end_fb_access: 126962306a36Sopenharmony_ci * 127062306a36Sopenharmony_ci * This hook cleans up resources allocated by @begin_fb_access. It it called 127162306a36Sopenharmony_ci * at the end of a commit for the new plane state. 127262306a36Sopenharmony_ci */ 127362306a36Sopenharmony_ci void (*end_fb_access)(struct drm_plane *plane, struct drm_plane_state *new_plane_state); 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci /** 127662306a36Sopenharmony_ci * @atomic_check: 127762306a36Sopenharmony_ci * 127862306a36Sopenharmony_ci * Drivers should check plane specific constraints in this hook. 127962306a36Sopenharmony_ci * 128062306a36Sopenharmony_ci * When using drm_atomic_helper_check_planes() plane's @atomic_check 128162306a36Sopenharmony_ci * hooks are called before the ones for CRTCs, which allows drivers to 128262306a36Sopenharmony_ci * request shared resources that the CRTC controls here. For more 128362306a36Sopenharmony_ci * complicated dependencies the driver can call the provided check helpers 128462306a36Sopenharmony_ci * multiple times until the computed state has a final configuration and 128562306a36Sopenharmony_ci * everything has been checked. 128662306a36Sopenharmony_ci * 128762306a36Sopenharmony_ci * This function is also allowed to inspect any other object's state and 128862306a36Sopenharmony_ci * can add more state objects to the atomic commit if needed. Care must 128962306a36Sopenharmony_ci * be taken though to ensure that state check and compute functions for 129062306a36Sopenharmony_ci * these added states are all called, and derived state in other objects 129162306a36Sopenharmony_ci * all updated. Again the recommendation is to just call check helpers 129262306a36Sopenharmony_ci * until a maximal configuration is reached. 129362306a36Sopenharmony_ci * 129462306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 129562306a36Sopenharmony_ci * optional. 129662306a36Sopenharmony_ci * 129762306a36Sopenharmony_ci * NOTE: 129862306a36Sopenharmony_ci * 129962306a36Sopenharmony_ci * This function is called in the check phase of an atomic update. The 130062306a36Sopenharmony_ci * driver is not allowed to change anything outside of the 130162306a36Sopenharmony_ci * &drm_atomic_state update tracking structure. 130262306a36Sopenharmony_ci * 130362306a36Sopenharmony_ci * RETURNS: 130462306a36Sopenharmony_ci * 130562306a36Sopenharmony_ci * 0 on success, -EINVAL if the state or the transition can't be 130662306a36Sopenharmony_ci * supported, -ENOMEM on memory allocation failure and -EDEADLK if an 130762306a36Sopenharmony_ci * attempt to obtain another state object ran into a &drm_modeset_lock 130862306a36Sopenharmony_ci * deadlock. 130962306a36Sopenharmony_ci */ 131062306a36Sopenharmony_ci int (*atomic_check)(struct drm_plane *plane, 131162306a36Sopenharmony_ci struct drm_atomic_state *state); 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci /** 131462306a36Sopenharmony_ci * @atomic_update: 131562306a36Sopenharmony_ci * 131662306a36Sopenharmony_ci * Drivers should use this function to update the plane state. This 131762306a36Sopenharmony_ci * hook is called in-between the &drm_crtc_helper_funcs.atomic_begin and 131862306a36Sopenharmony_ci * drm_crtc_helper_funcs.atomic_flush callbacks. 131962306a36Sopenharmony_ci * 132062306a36Sopenharmony_ci * Note that the power state of the display pipe when this function is 132162306a36Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 132262306a36Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 132362306a36Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 132462306a36Sopenharmony_ci * 132562306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is optional. 132662306a36Sopenharmony_ci */ 132762306a36Sopenharmony_ci void (*atomic_update)(struct drm_plane *plane, 132862306a36Sopenharmony_ci struct drm_atomic_state *state); 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci /** 133162306a36Sopenharmony_ci * @atomic_enable: 133262306a36Sopenharmony_ci * 133362306a36Sopenharmony_ci * Drivers should use this function to unconditionally enable a plane. 133462306a36Sopenharmony_ci * This hook is called in-between the &drm_crtc_helper_funcs.atomic_begin 133562306a36Sopenharmony_ci * and drm_crtc_helper_funcs.atomic_flush callbacks. It is called after 133662306a36Sopenharmony_ci * @atomic_update, which will be called for all enabled planes. Drivers 133762306a36Sopenharmony_ci * that use @atomic_enable should set up a plane in @atomic_update and 133862306a36Sopenharmony_ci * afterwards enable the plane in @atomic_enable. If a plane needs to be 133962306a36Sopenharmony_ci * enabled before installing the scanout buffer, drivers can still do 134062306a36Sopenharmony_ci * so in @atomic_update. 134162306a36Sopenharmony_ci * 134262306a36Sopenharmony_ci * Note that the power state of the display pipe when this function is 134362306a36Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 134462306a36Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 134562306a36Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 134662306a36Sopenharmony_ci * 134762306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 134862306a36Sopenharmony_ci * optional. If implemented, @atomic_enable should be the inverse of 134962306a36Sopenharmony_ci * @atomic_disable. Drivers that don't want to use either can still 135062306a36Sopenharmony_ci * implement the complete plane update in @atomic_update. 135162306a36Sopenharmony_ci */ 135262306a36Sopenharmony_ci void (*atomic_enable)(struct drm_plane *plane, 135362306a36Sopenharmony_ci struct drm_atomic_state *state); 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci /** 135662306a36Sopenharmony_ci * @atomic_disable: 135762306a36Sopenharmony_ci * 135862306a36Sopenharmony_ci * Drivers should use this function to unconditionally disable a plane. 135962306a36Sopenharmony_ci * This hook is called in-between the 136062306a36Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_begin and 136162306a36Sopenharmony_ci * drm_crtc_helper_funcs.atomic_flush callbacks. It is an alternative to 136262306a36Sopenharmony_ci * @atomic_update, which will be called for disabling planes, too, if 136362306a36Sopenharmony_ci * the @atomic_disable hook isn't implemented. 136462306a36Sopenharmony_ci * 136562306a36Sopenharmony_ci * This hook is also useful to disable planes in preparation of a modeset, 136662306a36Sopenharmony_ci * by calling drm_atomic_helper_disable_planes_on_crtc() from the 136762306a36Sopenharmony_ci * &drm_crtc_helper_funcs.disable hook. 136862306a36Sopenharmony_ci * 136962306a36Sopenharmony_ci * Note that the power state of the display pipe when this function is 137062306a36Sopenharmony_ci * called depends upon the exact helpers and calling sequence the driver 137162306a36Sopenharmony_ci * has picked. See drm_atomic_helper_commit_planes() for a discussion of 137262306a36Sopenharmony_ci * the tradeoffs and variants of plane commit helpers. 137362306a36Sopenharmony_ci * 137462306a36Sopenharmony_ci * This callback is used by the atomic modeset helpers, but it is 137562306a36Sopenharmony_ci * optional. It's intended to reverse the effects of @atomic_enable. 137662306a36Sopenharmony_ci */ 137762306a36Sopenharmony_ci void (*atomic_disable)(struct drm_plane *plane, 137862306a36Sopenharmony_ci struct drm_atomic_state *state); 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci /** 138162306a36Sopenharmony_ci * @atomic_async_check: 138262306a36Sopenharmony_ci * 138362306a36Sopenharmony_ci * Drivers should set this function pointer to check if the plane's 138462306a36Sopenharmony_ci * atomic state can be updated in a async fashion. Here async means 138562306a36Sopenharmony_ci * "not vblank synchronized". 138662306a36Sopenharmony_ci * 138762306a36Sopenharmony_ci * This hook is called by drm_atomic_async_check() to establish if a 138862306a36Sopenharmony_ci * given update can be committed asynchronously, that is, if it can 138962306a36Sopenharmony_ci * jump ahead of the state currently queued for update. 139062306a36Sopenharmony_ci * 139162306a36Sopenharmony_ci * RETURNS: 139262306a36Sopenharmony_ci * 139362306a36Sopenharmony_ci * Return 0 on success and any error returned indicates that the update 139462306a36Sopenharmony_ci * can not be applied in asynchronous manner. 139562306a36Sopenharmony_ci */ 139662306a36Sopenharmony_ci int (*atomic_async_check)(struct drm_plane *plane, 139762306a36Sopenharmony_ci struct drm_atomic_state *state); 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci /** 140062306a36Sopenharmony_ci * @atomic_async_update: 140162306a36Sopenharmony_ci * 140262306a36Sopenharmony_ci * Drivers should set this function pointer to perform asynchronous 140362306a36Sopenharmony_ci * updates of planes, that is, jump ahead of the currently queued 140462306a36Sopenharmony_ci * state and update the plane. Here async means "not vblank 140562306a36Sopenharmony_ci * synchronized". 140662306a36Sopenharmony_ci * 140762306a36Sopenharmony_ci * This hook is called by drm_atomic_helper_async_commit(). 140862306a36Sopenharmony_ci * 140962306a36Sopenharmony_ci * An async update will happen on legacy cursor updates. An async 141062306a36Sopenharmony_ci * update won't happen if there is an outstanding commit modifying 141162306a36Sopenharmony_ci * the same plane. 141262306a36Sopenharmony_ci * 141362306a36Sopenharmony_ci * When doing async_update drivers shouldn't replace the 141462306a36Sopenharmony_ci * &drm_plane_state but update the current one with the new plane 141562306a36Sopenharmony_ci * configurations in the new plane_state. 141662306a36Sopenharmony_ci * 141762306a36Sopenharmony_ci * Drivers should also swap the framebuffers between current plane 141862306a36Sopenharmony_ci * state (&drm_plane.state) and new_state. 141962306a36Sopenharmony_ci * This is required since cleanup for async commits is performed on 142062306a36Sopenharmony_ci * the new state, rather than old state like for traditional commits. 142162306a36Sopenharmony_ci * Since we want to give up the reference on the current (old) fb 142262306a36Sopenharmony_ci * instead of our brand new one, swap them in the driver during the 142362306a36Sopenharmony_ci * async commit. 142462306a36Sopenharmony_ci * 142562306a36Sopenharmony_ci * FIXME: 142662306a36Sopenharmony_ci * - It only works for single plane updates 142762306a36Sopenharmony_ci * - Async Pageflips are not supported yet 142862306a36Sopenharmony_ci * - Some hw might still scan out the old buffer until the next 142962306a36Sopenharmony_ci * vblank, however we let go of the fb references as soon as 143062306a36Sopenharmony_ci * we run this hook. For now drivers must implement their own workers 143162306a36Sopenharmony_ci * for deferring if needed, until a common solution is created. 143262306a36Sopenharmony_ci */ 143362306a36Sopenharmony_ci void (*atomic_async_update)(struct drm_plane *plane, 143462306a36Sopenharmony_ci struct drm_atomic_state *state); 143562306a36Sopenharmony_ci}; 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci/** 143862306a36Sopenharmony_ci * drm_plane_helper_add - sets the helper vtable for a plane 143962306a36Sopenharmony_ci * @plane: DRM plane 144062306a36Sopenharmony_ci * @funcs: helper vtable to set for @plane 144162306a36Sopenharmony_ci */ 144262306a36Sopenharmony_cistatic inline void drm_plane_helper_add(struct drm_plane *plane, 144362306a36Sopenharmony_ci const struct drm_plane_helper_funcs *funcs) 144462306a36Sopenharmony_ci{ 144562306a36Sopenharmony_ci plane->helper_private = funcs; 144662306a36Sopenharmony_ci} 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci/** 144962306a36Sopenharmony_ci * struct drm_mode_config_helper_funcs - global modeset helper operations 145062306a36Sopenharmony_ci * 145162306a36Sopenharmony_ci * These helper functions are used by the atomic helpers. 145262306a36Sopenharmony_ci */ 145362306a36Sopenharmony_cistruct drm_mode_config_helper_funcs { 145462306a36Sopenharmony_ci /** 145562306a36Sopenharmony_ci * @atomic_commit_tail: 145662306a36Sopenharmony_ci * 145762306a36Sopenharmony_ci * This hook is used by the default atomic_commit() hook implemented in 145862306a36Sopenharmony_ci * drm_atomic_helper_commit() together with the nonblocking commit 145962306a36Sopenharmony_ci * helpers (see drm_atomic_helper_setup_commit() for a starting point) 146062306a36Sopenharmony_ci * to implement blocking and nonblocking commits easily. It is not used 146162306a36Sopenharmony_ci * by the atomic helpers 146262306a36Sopenharmony_ci * 146362306a36Sopenharmony_ci * This function is called when the new atomic state has already been 146462306a36Sopenharmony_ci * swapped into the various state pointers. The passed in state 146562306a36Sopenharmony_ci * therefore contains copies of the old/previous state. This hook should 146662306a36Sopenharmony_ci * commit the new state into hardware. Note that the helpers have 146762306a36Sopenharmony_ci * already waited for preceeding atomic commits and fences, but drivers 146862306a36Sopenharmony_ci * can add more waiting calls at the start of their implementation, e.g. 146962306a36Sopenharmony_ci * to wait for driver-internal request for implicit syncing, before 147062306a36Sopenharmony_ci * starting to commit the update to the hardware. 147162306a36Sopenharmony_ci * 147262306a36Sopenharmony_ci * After the atomic update is committed to the hardware this hook needs 147362306a36Sopenharmony_ci * to call drm_atomic_helper_commit_hw_done(). Then wait for the update 147462306a36Sopenharmony_ci * to be executed by the hardware, for example using 147562306a36Sopenharmony_ci * drm_atomic_helper_wait_for_vblanks() or 147662306a36Sopenharmony_ci * drm_atomic_helper_wait_for_flip_done(), and then clean up the old 147762306a36Sopenharmony_ci * framebuffers using drm_atomic_helper_cleanup_planes(). 147862306a36Sopenharmony_ci * 147962306a36Sopenharmony_ci * When disabling a CRTC this hook _must_ stall for the commit to 148062306a36Sopenharmony_ci * complete. Vblank waits don't work on disabled CRTC, hence the core 148162306a36Sopenharmony_ci * can't take care of this. And it also can't rely on the vblank event, 148262306a36Sopenharmony_ci * since that can be signalled already when the screen shows black, 148362306a36Sopenharmony_ci * which can happen much earlier than the last hardware access needed to 148462306a36Sopenharmony_ci * shut off the display pipeline completely. 148562306a36Sopenharmony_ci * 148662306a36Sopenharmony_ci * This hook is optional, the default implementation is 148762306a36Sopenharmony_ci * drm_atomic_helper_commit_tail(). 148862306a36Sopenharmony_ci */ 148962306a36Sopenharmony_ci void (*atomic_commit_tail)(struct drm_atomic_state *state); 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci /** 149262306a36Sopenharmony_ci * @atomic_commit_setup: 149362306a36Sopenharmony_ci * 149462306a36Sopenharmony_ci * This hook is used by the default atomic_commit() hook implemented in 149562306a36Sopenharmony_ci * drm_atomic_helper_commit() together with the nonblocking helpers (see 149662306a36Sopenharmony_ci * drm_atomic_helper_setup_commit()) to extend the DRM commit setup. It 149762306a36Sopenharmony_ci * is not used by the atomic helpers. 149862306a36Sopenharmony_ci * 149962306a36Sopenharmony_ci * This function is called at the end of 150062306a36Sopenharmony_ci * drm_atomic_helper_setup_commit(), so once the commit has been 150162306a36Sopenharmony_ci * properly setup across the generic DRM object states. It allows 150262306a36Sopenharmony_ci * drivers to do some additional commit tracking that isn't related to a 150362306a36Sopenharmony_ci * CRTC, plane or connector, tracked in a &drm_private_obj structure. 150462306a36Sopenharmony_ci * 150562306a36Sopenharmony_ci * Note that the documentation of &drm_private_obj has more details on 150662306a36Sopenharmony_ci * how one should implement this. 150762306a36Sopenharmony_ci * 150862306a36Sopenharmony_ci * This hook is optional. 150962306a36Sopenharmony_ci */ 151062306a36Sopenharmony_ci int (*atomic_commit_setup)(struct drm_atomic_state *state); 151162306a36Sopenharmony_ci}; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci#endif 1514