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