18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2016 Noralf Trønnes
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H
78c2ecf20Sopenharmony_ci#define __LINUX_DRM_SIMPLE_KMS_HELPER_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <drm/drm_crtc.h>
108c2ecf20Sopenharmony_ci#include <drm/drm_encoder.h>
118c2ecf20Sopenharmony_ci#include <drm/drm_plane.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistruct drm_simple_display_pipe;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/**
168c2ecf20Sopenharmony_ci * struct drm_simple_display_pipe_funcs - helper operations for a simple
178c2ecf20Sopenharmony_ci *                                        display pipeline
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_cistruct drm_simple_display_pipe_funcs {
208c2ecf20Sopenharmony_ci	/**
218c2ecf20Sopenharmony_ci	 * @mode_valid:
228c2ecf20Sopenharmony_ci	 *
238c2ecf20Sopenharmony_ci	 * This callback is used to check if a specific mode is valid in the
248c2ecf20Sopenharmony_ci	 * crtc used in this simple display pipe. This should be implemented
258c2ecf20Sopenharmony_ci	 * if the display pipe has some sort of restriction in the modes
268c2ecf20Sopenharmony_ci	 * it can display. For example, a given display pipe may be responsible
278c2ecf20Sopenharmony_ci	 * to set a clock value. If the clock can not produce all the values
288c2ecf20Sopenharmony_ci	 * for the available modes then this callback can be used to restrict
298c2ecf20Sopenharmony_ci	 * the number of modes to only the ones that can be displayed. Another
308c2ecf20Sopenharmony_ci	 * reason can be bandwidth mitigation: the memory port on the display
318c2ecf20Sopenharmony_ci	 * controller can have bandwidth limitations not allowing pixel data
328c2ecf20Sopenharmony_ci	 * to be fetched at any rate.
338c2ecf20Sopenharmony_ci	 *
348c2ecf20Sopenharmony_ci	 * This hook is used by the probe helpers to filter the mode list in
358c2ecf20Sopenharmony_ci	 * drm_helper_probe_single_connector_modes(), and it is used by the
368c2ecf20Sopenharmony_ci	 * atomic helpers to validate modes supplied by userspace in
378c2ecf20Sopenharmony_ci	 * drm_atomic_helper_check_modeset().
388c2ecf20Sopenharmony_ci	 *
398c2ecf20Sopenharmony_ci	 * This function is optional.
408c2ecf20Sopenharmony_ci	 *
418c2ecf20Sopenharmony_ci	 * NOTE:
428c2ecf20Sopenharmony_ci	 *
438c2ecf20Sopenharmony_ci	 * Since this function is both called from the check phase of an atomic
448c2ecf20Sopenharmony_ci	 * commit, and the mode validation in the probe paths it is not allowed
458c2ecf20Sopenharmony_ci	 * to look at anything else but the passed-in mode, and validate it
468c2ecf20Sopenharmony_ci	 * against configuration-invariant hardware constraints.
478c2ecf20Sopenharmony_ci	 *
488c2ecf20Sopenharmony_ci	 * RETURNS:
498c2ecf20Sopenharmony_ci	 *
508c2ecf20Sopenharmony_ci	 * drm_mode_status Enum
518c2ecf20Sopenharmony_ci	 */
528c2ecf20Sopenharmony_ci	enum drm_mode_status (*mode_valid)(struct drm_simple_display_pipe *pipe,
538c2ecf20Sopenharmony_ci					   const struct drm_display_mode *mode);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/**
568c2ecf20Sopenharmony_ci	 * @enable:
578c2ecf20Sopenharmony_ci	 *
588c2ecf20Sopenharmony_ci	 * This function should be used to enable the pipeline.
598c2ecf20Sopenharmony_ci	 * It is called when the underlying crtc is enabled.
608c2ecf20Sopenharmony_ci	 * This hook is optional.
618c2ecf20Sopenharmony_ci	 */
628c2ecf20Sopenharmony_ci	void (*enable)(struct drm_simple_display_pipe *pipe,
638c2ecf20Sopenharmony_ci		       struct drm_crtc_state *crtc_state,
648c2ecf20Sopenharmony_ci		       struct drm_plane_state *plane_state);
658c2ecf20Sopenharmony_ci	/**
668c2ecf20Sopenharmony_ci	 * @disable:
678c2ecf20Sopenharmony_ci	 *
688c2ecf20Sopenharmony_ci	 * This function should be used to disable the pipeline.
698c2ecf20Sopenharmony_ci	 * It is called when the underlying crtc is disabled.
708c2ecf20Sopenharmony_ci	 * This hook is optional.
718c2ecf20Sopenharmony_ci	 */
728c2ecf20Sopenharmony_ci	void (*disable)(struct drm_simple_display_pipe *pipe);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	/**
758c2ecf20Sopenharmony_ci	 * @check:
768c2ecf20Sopenharmony_ci	 *
778c2ecf20Sopenharmony_ci	 * This function is called in the check phase of an atomic update,
788c2ecf20Sopenharmony_ci	 * specifically when the underlying plane is checked.
798c2ecf20Sopenharmony_ci	 * The simple display pipeline helpers already check that the plane is
808c2ecf20Sopenharmony_ci	 * not scaled, fills the entire visible area and is always enabled
818c2ecf20Sopenharmony_ci	 * when the crtc is also enabled.
828c2ecf20Sopenharmony_ci	 * This hook is optional.
838c2ecf20Sopenharmony_ci	 *
848c2ecf20Sopenharmony_ci	 * RETURNS:
858c2ecf20Sopenharmony_ci	 *
868c2ecf20Sopenharmony_ci	 * 0 on success, -EINVAL if the state or the transition can't be
878c2ecf20Sopenharmony_ci	 * supported, -ENOMEM on memory allocation failure and -EDEADLK if an
888c2ecf20Sopenharmony_ci	 * attempt to obtain another state object ran into a &drm_modeset_lock
898c2ecf20Sopenharmony_ci	 * deadlock.
908c2ecf20Sopenharmony_ci	 */
918c2ecf20Sopenharmony_ci	int (*check)(struct drm_simple_display_pipe *pipe,
928c2ecf20Sopenharmony_ci		     struct drm_plane_state *plane_state,
938c2ecf20Sopenharmony_ci		     struct drm_crtc_state *crtc_state);
948c2ecf20Sopenharmony_ci	/**
958c2ecf20Sopenharmony_ci	 * @update:
968c2ecf20Sopenharmony_ci	 *
978c2ecf20Sopenharmony_ci	 * This function is called when the underlying plane state is updated.
988c2ecf20Sopenharmony_ci	 * This hook is optional.
998c2ecf20Sopenharmony_ci	 *
1008c2ecf20Sopenharmony_ci	 * This is the function drivers should submit the
1018c2ecf20Sopenharmony_ci	 * &drm_pending_vblank_event from. Using either
1028c2ecf20Sopenharmony_ci	 * drm_crtc_arm_vblank_event(), when the driver supports vblank
1038c2ecf20Sopenharmony_ci	 * interrupt handling, or drm_crtc_send_vblank_event() for more
1048c2ecf20Sopenharmony_ci	 * complex case. In case the hardware lacks vblank support entirely,
1058c2ecf20Sopenharmony_ci	 * drivers can set &struct drm_crtc_state.no_vblank in
1068c2ecf20Sopenharmony_ci	 * &struct drm_simple_display_pipe_funcs.check and let DRM's
1078c2ecf20Sopenharmony_ci	 * atomic helper fake a vblank event.
1088c2ecf20Sopenharmony_ci	 */
1098c2ecf20Sopenharmony_ci	void (*update)(struct drm_simple_display_pipe *pipe,
1108c2ecf20Sopenharmony_ci		       struct drm_plane_state *old_plane_state);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	/**
1138c2ecf20Sopenharmony_ci	 * @prepare_fb:
1148c2ecf20Sopenharmony_ci	 *
1158c2ecf20Sopenharmony_ci	 * Optional, called by &drm_plane_helper_funcs.prepare_fb.  Please read
1168c2ecf20Sopenharmony_ci	 * the documentation for the &drm_plane_helper_funcs.prepare_fb hook for
1178c2ecf20Sopenharmony_ci	 * more details.
1188c2ecf20Sopenharmony_ci	 *
1198c2ecf20Sopenharmony_ci	 * Drivers which always have their buffers pinned should use
1208c2ecf20Sopenharmony_ci	 * drm_gem_fb_simple_display_pipe_prepare_fb() for this hook.
1218c2ecf20Sopenharmony_ci	 */
1228c2ecf20Sopenharmony_ci	int (*prepare_fb)(struct drm_simple_display_pipe *pipe,
1238c2ecf20Sopenharmony_ci			  struct drm_plane_state *plane_state);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	/**
1268c2ecf20Sopenharmony_ci	 * @cleanup_fb:
1278c2ecf20Sopenharmony_ci	 *
1288c2ecf20Sopenharmony_ci	 * Optional, called by &drm_plane_helper_funcs.cleanup_fb.  Please read
1298c2ecf20Sopenharmony_ci	 * the documentation for the &drm_plane_helper_funcs.cleanup_fb hook for
1308c2ecf20Sopenharmony_ci	 * more details.
1318c2ecf20Sopenharmony_ci	 */
1328c2ecf20Sopenharmony_ci	void (*cleanup_fb)(struct drm_simple_display_pipe *pipe,
1338c2ecf20Sopenharmony_ci			   struct drm_plane_state *plane_state);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	/**
1368c2ecf20Sopenharmony_ci	 * @enable_vblank:
1378c2ecf20Sopenharmony_ci	 *
1388c2ecf20Sopenharmony_ci	 * Optional, called by &drm_crtc_funcs.enable_vblank. Please read
1398c2ecf20Sopenharmony_ci	 * the documentation for the &drm_crtc_funcs.enable_vblank hook for
1408c2ecf20Sopenharmony_ci	 * more details.
1418c2ecf20Sopenharmony_ci	 */
1428c2ecf20Sopenharmony_ci	int (*enable_vblank)(struct drm_simple_display_pipe *pipe);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	/**
1458c2ecf20Sopenharmony_ci	 * @disable_vblank:
1468c2ecf20Sopenharmony_ci	 *
1478c2ecf20Sopenharmony_ci	 * Optional, called by &drm_crtc_funcs.disable_vblank. Please read
1488c2ecf20Sopenharmony_ci	 * the documentation for the &drm_crtc_funcs.disable_vblank hook for
1498c2ecf20Sopenharmony_ci	 * more details.
1508c2ecf20Sopenharmony_ci	 */
1518c2ecf20Sopenharmony_ci	void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
1528c2ecf20Sopenharmony_ci};
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/**
1558c2ecf20Sopenharmony_ci * struct drm_simple_display_pipe - simple display pipeline
1568c2ecf20Sopenharmony_ci * @crtc: CRTC control structure
1578c2ecf20Sopenharmony_ci * @plane: Plane control structure
1588c2ecf20Sopenharmony_ci * @encoder: Encoder control structure
1598c2ecf20Sopenharmony_ci * @connector: Connector control structure
1608c2ecf20Sopenharmony_ci * @funcs: Pipeline control functions (optional)
1618c2ecf20Sopenharmony_ci *
1628c2ecf20Sopenharmony_ci * Simple display pipeline with plane, crtc and encoder collapsed into one
1638c2ecf20Sopenharmony_ci * entity. It should be initialized by calling drm_simple_display_pipe_init().
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_cistruct drm_simple_display_pipe {
1668c2ecf20Sopenharmony_ci	struct drm_crtc crtc;
1678c2ecf20Sopenharmony_ci	struct drm_plane plane;
1688c2ecf20Sopenharmony_ci	struct drm_encoder encoder;
1698c2ecf20Sopenharmony_ci	struct drm_connector *connector;
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	const struct drm_simple_display_pipe_funcs *funcs;
1728c2ecf20Sopenharmony_ci};
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ciint drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe,
1758c2ecf20Sopenharmony_ci					  struct drm_bridge *bridge);
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ciint drm_simple_display_pipe_init(struct drm_device *dev,
1788c2ecf20Sopenharmony_ci			struct drm_simple_display_pipe *pipe,
1798c2ecf20Sopenharmony_ci			const struct drm_simple_display_pipe_funcs *funcs,
1808c2ecf20Sopenharmony_ci			const uint32_t *formats, unsigned int format_count,
1818c2ecf20Sopenharmony_ci			const uint64_t *format_modifiers,
1828c2ecf20Sopenharmony_ci			struct drm_connector *connector);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ciint drm_simple_encoder_init(struct drm_device *dev,
1858c2ecf20Sopenharmony_ci			    struct drm_encoder *encoder,
1868c2ecf20Sopenharmony_ci			    int encoder_type);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
189