2019-05-27 09:55:01 +03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2016-06-10 17:55:59 +03:00
/*
* Copyright ( C ) 2016 Noralf Trønnes
*/
# ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H
# define __LINUX_DRM_SIMPLE_KMS_HELPER_H
2017-01-22 21:11:11 +03:00
# include <drm/drm_crtc.h>
# include <drm/drm_encoder.h>
# include <drm/drm_plane.h>
2016-06-10 17:55:59 +03:00
struct drm_simple_display_pipe ;
/**
* struct drm_simple_display_pipe_funcs - helper operations for a simple
* display pipeline
*/
struct drm_simple_display_pipe_funcs {
2018-02-20 10:28:59 +03:00
/**
* @ mode_valid :
*
2018-02-27 13:11:09 +03:00
* This callback is used to check if a specific mode is valid in the
* crtc used in this simple display pipe . This should be implemented
* if the display pipe has some sort of restriction in the modes
* it can display . For example , a given display pipe may be responsible
* to set a clock value . If the clock can not produce all the values
* for the available modes then this callback can be used to restrict
* the number of modes to only the ones that can be displayed . Another
* reason can be bandwidth mitigation : the memory port on the display
* controller can have bandwidth limitations not allowing pixel data
* to be fetched at any rate .
*
* This hook is used by the probe helpers to filter the mode list in
* drm_helper_probe_single_connector_modes ( ) , and it is used by the
* atomic helpers to validate modes supplied by userspace in
* drm_atomic_helper_check_modeset ( ) .
*
* This function is optional .
*
* NOTE :
*
* Since this function is both called from the check phase of an atomic
* commit , and the mode validation in the probe paths it is not allowed
* to look at anything else but the passed - in mode , and validate it
* against configuration - invariant hardware constraints .
2018-02-20 10:28:59 +03:00
*
* RETURNS :
*
* drm_mode_status Enum
*/
2019-10-23 13:12:56 +03:00
enum drm_mode_status ( * mode_valid ) ( struct drm_simple_display_pipe * pipe ,
2018-02-20 10:28:59 +03:00
const struct drm_display_mode * mode ) ;
2016-06-10 17:55:59 +03:00
/**
* @ enable :
*
* This function should be used to enable the pipeline .
* It is called when the underlying crtc is enabled .
* This hook is optional .
*/
void ( * enable ) ( struct drm_simple_display_pipe * pipe ,
2018-03-22 23:27:37 +03:00
struct drm_crtc_state * crtc_state ,
struct drm_plane_state * plane_state ) ;
2016-06-10 17:55:59 +03:00
/**
* @ disable :
*
* This function should be used to disable the pipeline .
* It is called when the underlying crtc is disabled .
* This hook is optional .
*/
void ( * disable ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ check :
*
* This function is called in the check phase of an atomic update ,
* specifically when the underlying plane is checked .
* The simple display pipeline helpers already check that the plane is
* not scaled , fills the entire visible area and is always enabled
* when the crtc is also enabled .
* This hook is optional .
*
* RETURNS :
*
* 0 on success , - EINVAL if the state or the transition can ' t be
* supported , - ENOMEM on memory allocation failure and - EDEADLK if an
* attempt to obtain another state object ran into a & drm_modeset_lock
* deadlock .
*/
int ( * check ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ,
struct drm_crtc_state * crtc_state ) ;
/**
* @ update :
*
* This function is called when the underlying plane state is updated .
* This hook is optional .
2016-08-23 09:25:40 +03:00
*
* This is the function drivers should submit the
* & drm_pending_vblank_event from . Using either
* drm_crtc_arm_vblank_event ( ) , when the driver supports vblank
2020-01-29 15:05:17 +03:00
* interrupt handling , or drm_crtc_send_vblank_event ( ) for more
* complex case . In case the hardware lacks vblank support entirely ,
* drivers can set & struct drm_crtc_state . no_vblank in
* & struct drm_simple_display_pipe_funcs . check and let DRM ' s
* atomic helper fake a vblank event .
2016-06-10 17:55:59 +03:00
*/
void ( * update ) ( struct drm_simple_display_pipe * pipe ,
2017-03-21 02:36:15 +03:00
struct drm_plane_state * old_plane_state ) ;
2016-10-02 20:01:24 +03:00
/**
* @ prepare_fb :
*
2017-01-25 09:26:43 +03:00
* Optional , called by & drm_plane_helper_funcs . prepare_fb . Please read
* the documentation for the & drm_plane_helper_funcs . prepare_fb hook for
* more details .
2018-04-05 18:44:42 +03:00
*
2021-06-23 19:24:56 +03:00
* For GEM drivers who neither have a @ prepare_fb nor @ cleanup_fb hook
2022-12-02 15:56:37 +03:00
* set , drm_gem_plane_helper_prepare_fb ( ) is called automatically
2021-06-23 19:24:56 +03:00
* to implement this . Other drivers which need additional plane
2022-12-02 15:56:37 +03:00
* processing can call drm_gem_plane_helper_prepare_fb ( ) from
2021-06-23 19:24:56 +03:00
* their @ prepare_fb hook .
2016-10-02 20:01:24 +03:00
*/
int ( * prepare_fb ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
/**
* @ cleanup_fb :
*
2017-01-25 09:26:43 +03:00
* Optional , called by & drm_plane_helper_funcs . cleanup_fb . Please read
* the documentation for the & drm_plane_helper_funcs . cleanup_fb hook for
* more details .
2016-10-02 20:01:24 +03:00
*/
void ( * cleanup_fb ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
2018-02-12 11:52:51 +03:00
2022-10-25 13:17:36 +03:00
/**
* @ begin_fb_access :
*
* Optional , called by & drm_plane_helper_funcs . begin_fb_access . Please read
* the documentation for the & drm_plane_helper_funcs . begin_fb_access hook for
* more details .
*/
int ( * begin_fb_access ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * new_plane_state ) ;
/**
* @ end_fb_access :
*
* Optional , called by & drm_plane_helper_funcs . end_fb_access . Please read
* the documentation for the & drm_plane_helper_funcs . end_fb_access hook for
* more details .
*/
void ( * end_fb_access ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
2018-02-12 11:52:51 +03:00
/**
* @ enable_vblank :
*
* Optional , called by & drm_crtc_funcs . enable_vblank . Please read
* the documentation for the & drm_crtc_funcs . enable_vblank hook for
* more details .
*/
int ( * enable_vblank ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ disable_vblank :
*
* Optional , called by & drm_crtc_funcs . disable_vblank . Please read
* the documentation for the & drm_crtc_funcs . disable_vblank hook for
* more details .
*/
void ( * disable_vblank ) ( struct drm_simple_display_pipe * pipe ) ;
2021-02-08 14:55:32 +03:00
2021-07-14 17:22:38 +03:00
/**
* @ reset_crtc :
*
* Optional , called by & drm_crtc_funcs . reset . Please read the
* documentation for the & drm_crtc_funcs . reset hook for more details .
*/
void ( * reset_crtc ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ duplicate_crtc_state :
*
* Optional , called by & drm_crtc_funcs . atomic_duplicate_state . Please
* read the documentation for the & drm_crtc_funcs . atomic_duplicate_state
* hook for more details .
*/
struct drm_crtc_state * ( * duplicate_crtc_state ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ destroy_crtc_state :
*
* Optional , called by & drm_crtc_funcs . atomic_destroy_state . Please
* read the documentation for the & drm_crtc_funcs . atomic_destroy_state
* hook for more details .
*/
void ( * destroy_crtc_state ) ( struct drm_simple_display_pipe * pipe ,
struct drm_crtc_state * crtc_state ) ;
2021-02-08 14:55:32 +03:00
/**
* @ reset_plane :
*
* Optional , called by & drm_plane_funcs . reset . Please read the
* documentation for the & drm_plane_funcs . reset hook for more details .
*/
void ( * reset_plane ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ duplicate_plane_state :
*
* Optional , called by & drm_plane_funcs . atomic_duplicate_state . Please
* read the documentation for the & drm_plane_funcs . atomic_duplicate_state
* hook for more details .
*/
struct drm_plane_state * ( * duplicate_plane_state ) ( struct drm_simple_display_pipe * pipe ) ;
/**
* @ destroy_plane_state :
*
* Optional , called by & drm_plane_funcs . atomic_destroy_state . Please
* read the documentation for the & drm_plane_funcs . atomic_destroy_state
* hook for more details .
*/
void ( * destroy_plane_state ) ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
2016-06-10 17:55:59 +03:00
} ;
/**
* struct drm_simple_display_pipe - simple display pipeline
* @ crtc : CRTC control structure
* @ plane : Plane control structure
* @ encoder : Encoder control structure
* @ connector : Connector control structure
* @ funcs : Pipeline control functions ( optional )
*
* Simple display pipeline with plane , crtc and encoder collapsed into one
* entity . It should be initialized by calling drm_simple_display_pipe_init ( ) .
*/
struct drm_simple_display_pipe {
struct drm_crtc crtc ;
struct drm_plane plane ;
struct drm_encoder encoder ;
struct drm_connector * connector ;
const struct drm_simple_display_pipe_funcs * funcs ;
} ;
2016-08-25 12:04:34 +03:00
int drm_simple_display_pipe_attach_bridge ( struct drm_simple_display_pipe * pipe ,
struct drm_bridge * bridge ) ;
2016-06-10 17:55:59 +03:00
int drm_simple_display_pipe_init ( struct drm_device * dev ,
struct drm_simple_display_pipe * pipe ,
const struct drm_simple_display_pipe_funcs * funcs ,
const uint32_t * formats , unsigned int format_count ,
2017-07-24 06:46:38 +03:00
const uint64_t * format_modifiers ,
2016-06-10 17:55:59 +03:00
struct drm_connector * connector ) ;
2020-02-28 11:18:25 +03:00
int drm_simple_encoder_init ( struct drm_device * dev ,
struct drm_encoder * encoder ,
int encoder_type ) ;
2020-12-10 18:38:29 +03:00
void * __drmm_simple_encoder_alloc ( struct drm_device * dev , size_t size ,
size_t offset , int encoder_type ) ;
/**
* drmm_simple_encoder_alloc - Allocate and initialize an encoder with basic
* functionality .
* @ dev : drm device
* @ type : the type of the struct which contains struct & drm_encoder
* @ member : the name of the & drm_encoder within @ type .
* @ encoder_type : user visible type of the encoder
*
* Allocates and initializes an encoder that has no further functionality .
* Settings for possible CRTC and clones are left to their initial values .
* Cleanup is automatically handled through registering drm_encoder_cleanup ( )
* with drmm_add_action ( ) .
*
* Returns :
* Pointer to new encoder , or ERR_PTR on failure .
*/
# define drmm_simple_encoder_alloc(dev, type, member, encoder_type) \
( ( type * ) __drmm_simple_encoder_alloc ( dev , sizeof ( type ) , \
offsetof ( type , member ) , \
encoder_type ) )
2016-06-10 17:55:59 +03:00
# endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */