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