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/list.h>
# include <linux/ctype.h>
2016-08-29 11:27:51 +03:00
# include <drm/drm_mode_object.h>
2016-08-15 17:07:02 +03:00
struct drm_framebuffer ;
struct drm_file ;
struct drm_device ;
/**
* 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
* framebuffer successfully created by - > fb_create ( ) in
* & drm_mode_config_funcs . Drivers must also call
* 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
* GEM or TTM ) valid for the passed - in struct & drm_file . This is used by
* 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 .
*
* 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
* userspace perspective . See drm_framebuffer_reference ( ) and
* drm_framebuffer_unreference ( ) .
*
* 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
/**
* @ head : Place on the dev - > mode_config . fb_list , access protected by
2016-08-15 17:07:02 +03:00
* dev - > mode_config . fb_lock .
*/
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 ;
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
* instead done through the source rectangle in struct & drm_plane_state .
*/
2016-08-15 17:07:02 +03:00
unsigned int offsets [ 4 ] ;
2016-08-12 23:48:48 +03:00
/**
* @ modifier : Data layout modifier , per buffer . This is used to describe
* tiling , or also special layouts ( like compression ) of auxiliary
* buffers . For userspace created object this is copied from
* drm_mode_fb_cmd2 .
*/
2016-08-15 17:07:02 +03:00
uint64_t modifier [ 4 ] ;
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
/**
* @ depth : Depth in bits per pixel for RGB formats . 0 for everything
* else . Legacy information derived from @ pixel_format , it ' s suggested to use
* the DRM FOURCC codes and helper functions directly instead .
*/
2016-08-15 17:07:02 +03:00
unsigned int depth ;
2016-08-12 23:48:48 +03:00
/**
* @ bits_per_pixel : Storage used bits per pixel for RGB formats . 0 for
* everything else . Legacy information derived from @ pixel_format , it ' s
* suggested to use the DRM FOURCC codes and helper functions directly
* instead .
*/
2016-08-15 17:07:02 +03:00
int bits_per_pixel ;
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
/**
* @ pixel_format : DRM FOURCC code describing the pixel format .
*/
2016-08-15 17:07:02 +03:00
uint32_t pixel_format ; /* fourcc format */
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
/**
* @ filp_head : Placed on struct & drm_file fbs list_head , protected by
* fbs_lock in the same structure .
*/
2016-08-15 17:07:02 +03:00
struct list_head filp_head ;
} ;
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 ,
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 ) ;
/**
* drm_framebuffer_reference - incr the fb refcnt
* @ fb : framebuffer
*
* This functions increments the fb ' s refcount .
*/
static inline void drm_framebuffer_reference ( struct drm_framebuffer * fb )
{
drm_mode_object_reference ( & fb - > base ) ;
}
/**
* drm_framebuffer_unreference - unref a framebuffer
* @ fb : framebuffer to unref
*
* This functions decrements the fb ' s refcount and frees it if it drops to zero .
*/
static inline void drm_framebuffer_unreference ( struct drm_framebuffer * fb )
{
drm_mode_object_unreference ( & fb - > base ) ;
}
/**
* drm_framebuffer_read_refcount - read the framebuffer reference count .
* @ fb : framebuffer
*
* This functions returns the framebuffer ' s reference count .
*/
static inline uint32_t drm_framebuffer_read_refcount ( struct drm_framebuffer * fb )
{
return atomic_read ( & fb - > base . refcount . refcount ) ;
}
2016-08-31 19:09:04 +03:00
/**
* drm_for_each_fb - iterate over all framebuffers
* @ fb : the loop cursor
* @ dev : the DRM device
*
* Iterate over all framebuffers of @ dev . User must hold the fb_lock from
* & drm_mode_config .
*/
# 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-08-15 17:07:02 +03:00
# endif