2016-08-15 17:07:02 +03:00
/*
* Copyright ( c ) 2016 Intel Corporation
*
* Permission to use , copy , modify , distribute , and sell this software and its
* documentation for any purpose is hereby granted without fee , provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation , and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific ,
* written prior permission . The copyright holders make no representations
* about the suitability of this software for any purpose . It is provided " as
* is " without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS , IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL , INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE ,
* DATA OR PROFITS , WHETHER IN AN ACTION OF CONTRACT , NEGLIGENCE OR OTHER
* TORTIOUS ACTION , ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE .
*/
# ifndef __DRM_FRAMEBUFFER_H__
# define __DRM_FRAMEBUFFER_H__
# include <linux/ctype.h>
2019-01-08 22:29:30 +03:00
# include <linux/list.h>
# include <linux/sched.h>
2016-08-29 11:27:51 +03:00
# include <drm/drm_mode_object.h>
2016-08-15 17:07:02 +03:00
2019-01-08 22:29:30 +03:00
struct drm_clip_rect ;
2016-08-15 17:07:02 +03:00
struct drm_device ;
2019-01-08 22:29:30 +03:00
struct drm_file ;
2019-03-13 13:29:05 +03:00
struct drm_format_info ;
2019-01-08 22:29:30 +03:00
struct drm_framebuffer ;
struct drm_gem_object ;
2016-08-15 17:07:02 +03:00
/**
* struct drm_framebuffer_funcs - framebuffer hooks
*/
struct drm_framebuffer_funcs {
/**
* @ destroy :
*
* Clean up framebuffer resources , specifically also unreference the
* backing storage . The core guarantees to call this function for every
2017-01-25 09:26:45 +03:00
* framebuffer successfully created by calling
* & drm_mode_config_funcs . fb_create . Drivers must also call
2016-08-15 17:07:02 +03:00
* drm_framebuffer_cleanup ( ) to release DRM core resources for this
* framebuffer .
*/
void ( * destroy ) ( struct drm_framebuffer * framebuffer ) ;
/**
* @ create_handle :
*
* Create a buffer handle in the driver - specific buffer manager ( either
2016-12-29 23:48:26 +03:00
* GEM or TTM ) valid for the passed - in & struct drm_file . This is used by
2016-08-15 17:07:02 +03:00
* the core to implement the GETFB IOCTL , which returns ( for
* sufficiently priviledged user ) also a native buffer handle . This can
* be used for seamless transitions between modesetting clients by
* copying the current screen contents to a private buffer and blending
* between that and the new contents .
*
* GEM based drivers should call drm_gem_handle_create ( ) to create the
* handle .
*
* RETURNS :
*
* 0 on success or a negative error code on failure .
*/
int ( * create_handle ) ( struct drm_framebuffer * fb ,
struct drm_file * file_priv ,
unsigned int * handle ) ;
/**
* @ dirty :
*
* Optional callback for the dirty fb IOCTL .
*
* Userspace can notify the driver via this callback that an area of the
* framebuffer has changed and should be flushed to the display
* hardware . This can also be used internally , e . g . by the fbdev
* emulation , though that ' s not the case currently .
*
* See documentation in drm_mode . h for the struct drm_mode_fb_dirty_cmd
* for more information as all the semantics and arguments have a one to
* one mapping on this function .
*
2019-06-11 14:28:59 +03:00
* Atomic drivers should use drm_atomic_helper_dirtyfb ( ) to implement
* this hook .
*
2016-08-15 17:07:02 +03:00
* RETURNS :
*
* 0 on success or a negative error code on failure .
*/
int ( * dirty ) ( struct drm_framebuffer * framebuffer ,
struct drm_file * file_priv , unsigned flags ,
unsigned color , struct drm_clip_rect * clips ,
unsigned num_clips ) ;
} ;
2016-08-12 23:48:48 +03:00
/**
* struct drm_framebuffer - frame buffer object
*
* Note that the fb is refcounted for the benefit of driver internals ,
* for example some hw , disabling a CRTC / plane is asynchronous , and
* scanout does not actually complete until the next vblank . So some
* cleanup ( like releasing the reference ( s ) on the backing GEM bo ( s ) )
* should be deferred . In cases like this , the driver would like to
* hold a ref to the fb even though it has already been removed from
2017-02-28 17:46:40 +03:00
* userspace perspective . See drm_framebuffer_get ( ) and
* drm_framebuffer_put ( ) .
2016-08-12 23:48:48 +03:00
*
* The refcount is stored inside the mode object @ base .
*/
2016-08-15 17:07:02 +03:00
struct drm_framebuffer {
2016-08-12 23:48:48 +03:00
/**
* @ dev : DRM device this framebuffer belongs to
*/
2016-08-15 17:07:02 +03:00
struct drm_device * dev ;
2016-08-12 23:48:48 +03:00
/**
2017-01-25 09:26:45 +03:00
* @ head : Place on the & drm_mode_config . fb_list , access protected by
* & drm_mode_config . fb_lock .
2016-08-15 17:07:02 +03:00
*/
struct list_head head ;
2016-08-12 23:48:48 +03:00
/**
* @ base : base modeset object structure , contains the reference count .
*/
2016-08-15 17:07:02 +03:00
struct drm_mode_object base ;
2017-12-20 12:35:44 +03:00
/**
* @ comm : Name of the process allocating the fb , used for fb dumping .
*/
char comm [ TASK_COMM_LEN ] ;
2016-11-18 22:52:55 +03:00
/**
* @ format : framebuffer format information
*/
const struct drm_format_info * format ;
2016-08-12 23:48:48 +03:00
/**
* @ funcs : framebuffer vfunc table
*/
2016-08-15 17:07:02 +03:00
const struct drm_framebuffer_funcs * funcs ;
2016-08-12 23:48:48 +03:00
/**
* @ pitches : Line stride per buffer . For userspace created object this
* is copied from drm_mode_fb_cmd2 .
*/
2016-08-15 17:07:02 +03:00
unsigned int pitches [ 4 ] ;
2016-08-12 23:48:48 +03:00
/**
* @ offsets : Offset from buffer start to the actual pixel data in bytes ,
* per buffer . For userspace created object this is copied from
* drm_mode_fb_cmd2 .
*
* Note that this is a linear offset and does not take into account
* tiling or buffer laytou per @ modifier . It meant to be used when the
* actual pixel data for this framebuffer plane starts at an offset ,
* e . g . when multiple planes are allocated within the same backing
* storage buffer object . For tiled layouts this generally means it
* @ offsets must at least be tile - size aligned , but hardware often has
* stricter requirements .
*
* This should not be used to specifiy x / y pixel offsets into the buffer
* data ( even for linear buffers ) . Specifying an x / y pixel offset is
2016-12-29 23:48:26 +03:00
* instead done through the source rectangle in & struct drm_plane_state .
2016-08-12 23:48:48 +03:00
*/
2016-08-15 17:07:02 +03:00
unsigned int offsets [ 4 ] ;
2016-08-12 23:48:48 +03:00
/**
2016-11-16 14:33:16 +03:00
* @ modifier : Data layout modifier . This is used to describe
2016-08-12 23:48:48 +03:00
* tiling , or also special layouts ( like compression ) of auxiliary
* buffers . For userspace created object this is copied from
* drm_mode_fb_cmd2 .
*/
2016-11-16 14:33:16 +03:00
uint64_t modifier ;
2016-08-12 23:48:48 +03:00
/**
* @ width : Logical width of the visible area of the framebuffer , in
* pixels .
*/
2016-08-15 17:07:02 +03:00
unsigned int width ;
2016-08-12 23:48:48 +03:00
/**
* @ height : Logical height of the visible area of the framebuffer , in
* pixels .
*/
2016-08-15 17:07:02 +03:00
unsigned int height ;
2016-08-12 23:48:48 +03:00
/**
* @ flags : Framebuffer flags like DRM_MODE_FB_INTERLACED or
* DRM_MODE_FB_MODIFIERS .
*/
2016-08-15 17:07:02 +03:00
int flags ;
2016-08-12 23:48:48 +03:00
/**
* @ hot_x : X coordinate of the cursor hotspot . Used by the legacy cursor
* IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
* universal plane .
*/
2016-08-15 17:07:02 +03:00
int hot_x ;
2016-08-12 23:48:48 +03:00
/**
* @ hot_y : Y coordinate of the cursor hotspot . Used by the legacy cursor
* IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
* universal plane .
*/
2016-08-15 17:07:02 +03:00
int hot_y ;
2016-08-12 23:48:48 +03:00
/**
2017-01-25 09:26:45 +03:00
* @ filp_head : Placed on & drm_file . fbs , protected by & drm_file . fbs_lock .
2016-08-12 23:48:48 +03:00
*/
2016-08-15 17:07:02 +03:00
struct list_head filp_head ;
2017-08-13 16:31:44 +03:00
/**
* @ obj : GEM objects backing the framebuffer , one per plane ( optional ) .
*
* This is used by the GEM framebuffer helpers , see e . g .
* drm_gem_fb_create ( ) .
*/
struct drm_gem_object * obj [ 4 ] ;
2016-08-15 17:07:02 +03:00
} ;
2016-08-31 19:09:04 +03:00
# define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
2016-08-15 17:07:02 +03:00
int drm_framebuffer_init ( struct drm_device * dev ,
struct drm_framebuffer * fb ,
const struct drm_framebuffer_funcs * funcs ) ;
struct drm_framebuffer * drm_framebuffer_lookup ( struct drm_device * dev ,
2017-03-15 09:25:07 +03:00
struct drm_file * file_priv ,
2016-08-15 17:07:02 +03:00
uint32_t id ) ;
void drm_framebuffer_remove ( struct drm_framebuffer * fb ) ;
void drm_framebuffer_cleanup ( struct drm_framebuffer * fb ) ;
void drm_framebuffer_unregister_private ( struct drm_framebuffer * fb ) ;
/**
2017-02-28 17:46:40 +03:00
* drm_framebuffer_get - acquire a framebuffer reference
* @ fb : DRM framebuffer
*
* This function increments the framebuffer ' s reference count .
*/
static inline void drm_framebuffer_get ( struct drm_framebuffer * fb )
{
drm_mode_object_get ( & fb - > base ) ;
}
/**
* drm_framebuffer_put - release a framebuffer reference
* @ fb : DRM framebuffer
*
* This function decrements the framebuffer ' s reference count and frees the
* framebuffer if the reference count drops to zero .
*/
static inline void drm_framebuffer_put ( struct drm_framebuffer * fb )
{
drm_mode_object_put ( & fb - > base ) ;
}
2016-08-15 17:07:02 +03:00
/**
* drm_framebuffer_read_refcount - read the framebuffer reference count .
* @ fb : framebuffer
*
* This functions returns the framebuffer ' s reference count .
*/
2017-11-07 22:13:38 +03:00
static inline uint32_t drm_framebuffer_read_refcount ( const struct drm_framebuffer * fb )
2016-08-15 17:07:02 +03:00
{
2016-11-14 19:29:48 +03:00
return kref_read ( & fb - > base . refcount ) ;
2016-08-15 17:07:02 +03:00
}
2016-08-31 19:09:04 +03:00
/**
2016-11-25 18:32:30 +03:00
* drm_framebuffer_assign - store a reference to the fb
* @ p : location to store framebuffer
* @ fb : new framebuffer ( maybe NULL )
*
* This functions sets the location to store a reference to the framebuffer ,
* unreferencing the framebuffer that was previously stored in that location .
*/
static inline void drm_framebuffer_assign ( struct drm_framebuffer * * p ,
struct drm_framebuffer * fb )
{
if ( fb )
2017-02-28 17:46:40 +03:00
drm_framebuffer_get ( fb ) ;
2016-11-25 18:32:30 +03:00
if ( * p )
2017-02-28 17:46:40 +03:00
drm_framebuffer_put ( * p ) ;
2016-11-25 18:32:30 +03:00
* p = fb ;
}
/*
2016-08-31 19:09:04 +03:00
* drm_for_each_fb - iterate over all framebuffers
* @ fb : the loop cursor
* @ dev : the DRM device
*
2017-01-25 09:26:45 +03:00
* Iterate over all framebuffers of @ dev . User must hold
* & drm_mode_config . fb_lock .
2016-08-31 19:09:04 +03:00
*/
# define drm_for_each_fb(fb, dev) \
for ( WARN_ON ( ! mutex_is_locked ( & ( dev ) - > mode_config . fb_lock ) ) , \
fb = list_first_entry ( & ( dev ) - > mode_config . fb_list , \
struct drm_framebuffer , head ) ; \
& fb - > head ! = ( & ( dev ) - > mode_config . fb_list ) ; \
fb = list_next_entry ( fb , head ) )
2016-11-18 22:53:05 +03:00
int drm_framebuffer_plane_width ( int width ,
const struct drm_framebuffer * fb , int plane ) ;
int drm_framebuffer_plane_height ( int height ,
const struct drm_framebuffer * fb , int plane ) ;
2020-03-11 17:55:37 +03:00
/**
* struct drm_afbc_framebuffer - a special afbc frame buffer object
*
* A derived class of struct drm_framebuffer , dedicated for afbc use cases .
*/
struct drm_afbc_framebuffer {
/**
* @ base : base framebuffer structure .
*/
struct drm_framebuffer base ;
/**
2020-03-28 16:20:21 +03:00
* @ block_width : width of a single afbc block
2020-03-11 17:55:37 +03:00
*/
u32 block_width ;
/**
2020-03-28 16:20:21 +03:00
* @ block_height : height of a single afbc block
2020-03-11 17:55:37 +03:00
*/
u32 block_height ;
/**
* @ aligned_width : aligned frame buffer width
*/
u32 aligned_width ;
/**
* @ aligned_height : aligned frame buffer height
*/
u32 aligned_height ;
/**
* @ offset : offset of the first afbc header
*/
u32 offset ;
/**
* @ afbc_size : minimum size of afbc buffer
*/
u32 afbc_size ;
} ;
# define fb_to_afbc_fb(x) container_of(x, struct drm_afbc_framebuffer, base)
2016-08-15 17:07:02 +03:00
# endif