/*1* Copyright (c) 2016 Intel Corporation2*3* Permission to use, copy, modify, distribute, and sell this software and its4* documentation for any purpose is hereby granted without fee, provided that5* the above copyright notice appear in all copies and that both that copyright6* notice and this permission notice appear in supporting documentation, and7* that the name of the copyright holders not be used in advertising or8* publicity pertaining to distribution of the software without specific,9* written prior permission. The copyright holders make no representations10* about the suitability of this software for any purpose. It is provided "as11* is" without express or implied warranty.12*13* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,14* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO15* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR16* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,17* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER18* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE19* OF THIS SOFTWARE.20*/2122#ifndef __DRM_FRAMEBUFFER_H__23#define __DRM_FRAMEBUFFER_H__2425#include <linux/bits.h>26#include <linux/ctype.h>27#include <linux/list.h>28#include <linux/sched.h>2930#include <drm/drm_fourcc.h>31#include <drm/drm_mode_object.h>3233struct drm_clip_rect;34struct drm_device;35struct drm_file;36struct drm_framebuffer;37struct drm_gem_object;3839/**40* struct drm_framebuffer_funcs - framebuffer hooks41*/42struct drm_framebuffer_funcs {43/**44* @destroy:45*46* Clean up framebuffer resources, specifically also unreference the47* backing storage. The core guarantees to call this function for every48* framebuffer successfully created by calling49* &drm_mode_config_funcs.fb_create. Drivers must also call50* drm_framebuffer_cleanup() to release DRM core resources for this51* framebuffer.52*/53void (*destroy)(struct drm_framebuffer *framebuffer);5455/**56* @create_handle:57*58* Create a buffer handle in the driver-specific buffer manager (either59* GEM or TTM) valid for the passed-in &struct drm_file. This is used by60* the core to implement the GETFB IOCTL, which returns (for61* sufficiently priviledged user) also a native buffer handle. This can62* be used for seamless transitions between modesetting clients by63* copying the current screen contents to a private buffer and blending64* between that and the new contents.65*66* GEM based drivers should call drm_gem_handle_create() to create the67* handle.68*69* RETURNS:70*71* 0 on success or a negative error code on failure.72*/73int (*create_handle)(struct drm_framebuffer *fb,74struct drm_file *file_priv,75unsigned int *handle);76/**77* @dirty:78*79* Optional callback for the dirty fb IOCTL.80*81* Userspace can notify the driver via this callback that an area of the82* framebuffer has changed and should be flushed to the display83* hardware. This can also be used internally, e.g. by the fbdev84* emulation, though that's not the case currently.85*86* See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd87* for more information as all the semantics and arguments have a one to88* one mapping on this function.89*90* Atomic drivers should use drm_atomic_helper_dirtyfb() to implement91* this hook.92*93* RETURNS:94*95* 0 on success or a negative error code on failure.96*/97int (*dirty)(struct drm_framebuffer *framebuffer,98struct drm_file *file_priv, unsigned flags,99unsigned color, struct drm_clip_rect *clips,100unsigned num_clips);101};102103#define DRM_FRAMEBUFFER_HAS_HANDLE_REF(_i) BIT(0u + (_i))104105/**106* struct drm_framebuffer - frame buffer object107*108* Note that the fb is refcounted for the benefit of driver internals,109* for example some hw, disabling a CRTC/plane is asynchronous, and110* scanout does not actually complete until the next vblank. So some111* cleanup (like releasing the reference(s) on the backing GEM bo(s))112* should be deferred. In cases like this, the driver would like to113* hold a ref to the fb even though it has already been removed from114* userspace perspective. See drm_framebuffer_get() and115* drm_framebuffer_put().116*117* The refcount is stored inside the mode object @base.118*/119struct drm_framebuffer {120/**121* @dev: DRM device this framebuffer belongs to122*/123struct drm_device *dev;124/**125* @head: Place on the &drm_mode_config.fb_list, access protected by126* &drm_mode_config.fb_lock.127*/128struct list_head head;129130/**131* @base: base modeset object structure, contains the reference count.132*/133struct drm_mode_object base;134135/**136* @comm: Name of the process allocating the fb, used for fb dumping.137*/138char comm[TASK_COMM_LEN];139140/**141* @format: framebuffer format information142*/143const struct drm_format_info *format;144/**145* @funcs: framebuffer vfunc table146*/147const struct drm_framebuffer_funcs *funcs;148/**149* @pitches: Line stride per buffer. For userspace created object this150* is copied from drm_mode_fb_cmd2.151*/152unsigned int pitches[DRM_FORMAT_MAX_PLANES];153/**154* @offsets: Offset from buffer start to the actual pixel data in bytes,155* per buffer. For userspace created object this is copied from156* drm_mode_fb_cmd2.157*158* Note that this is a linear offset and does not take into account159* tiling or buffer layout per @modifier. It is meant to be used when160* the actual pixel data for this framebuffer plane starts at an offset,161* e.g. when multiple planes are allocated within the same backing162* storage buffer object. For tiled layouts this generally means its163* @offsets must at least be tile-size aligned, but hardware often has164* stricter requirements.165*166* This should not be used to specifiy x/y pixel offsets into the buffer167* data (even for linear buffers). Specifying an x/y pixel offset is168* instead done through the source rectangle in &struct drm_plane_state.169*/170unsigned int offsets[DRM_FORMAT_MAX_PLANES];171/**172* @modifier: Data layout modifier. This is used to describe173* tiling, or also special layouts (like compression) of auxiliary174* buffers. For userspace created object this is copied from175* drm_mode_fb_cmd2.176*/177uint64_t modifier;178/**179* @width: Logical width of the visible area of the framebuffer, in180* pixels.181*/182unsigned int width;183/**184* @height: Logical height of the visible area of the framebuffer, in185* pixels.186*/187unsigned int height;188/**189* @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or190* DRM_MODE_FB_MODIFIERS.191*/192int flags;193/**194* @internal_flags: Framebuffer flags like DRM_FRAMEBUFFER_HAS_HANDLE_REF.195*/196unsigned int internal_flags;197/**198* @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.199*/200struct list_head filp_head;201/**202* @obj: GEM objects backing the framebuffer, one per plane (optional).203*204* This is used by the GEM framebuffer helpers, see e.g.205* drm_gem_fb_create().206*/207struct drm_gem_object *obj[DRM_FORMAT_MAX_PLANES];208};209210#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)211212int drm_framebuffer_init(struct drm_device *dev,213struct drm_framebuffer *fb,214const struct drm_framebuffer_funcs *funcs);215struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,216struct drm_file *file_priv,217uint32_t id);218void drm_framebuffer_remove(struct drm_framebuffer *fb);219void drm_framebuffer_cleanup(struct drm_framebuffer *fb);220void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);221222/**223* drm_framebuffer_get - acquire a framebuffer reference224* @fb: DRM framebuffer225*226* This function increments the framebuffer's reference count.227*/228static inline void drm_framebuffer_get(struct drm_framebuffer *fb)229{230drm_mode_object_get(&fb->base);231}232233/**234* drm_framebuffer_put - release a framebuffer reference235* @fb: DRM framebuffer236*237* This function decrements the framebuffer's reference count and frees the238* framebuffer if the reference count drops to zero.239*/240static inline void drm_framebuffer_put(struct drm_framebuffer *fb)241{242drm_mode_object_put(&fb->base);243}244245/**246* drm_framebuffer_read_refcount - read the framebuffer reference count.247* @fb: framebuffer248*249* This functions returns the framebuffer's reference count.250*/251static inline uint32_t drm_framebuffer_read_refcount(const struct drm_framebuffer *fb)252{253return kref_read(&fb->base.refcount);254}255256/**257* drm_framebuffer_assign - store a reference to the fb258* @p: location to store framebuffer259* @fb: new framebuffer (maybe NULL)260*261* This functions sets the location to store a reference to the framebuffer,262* unreferencing the framebuffer that was previously stored in that location.263*/264static inline void drm_framebuffer_assign(struct drm_framebuffer **p,265struct drm_framebuffer *fb)266{267if (fb)268drm_framebuffer_get(fb);269if (*p)270drm_framebuffer_put(*p);271*p = fb;272}273274/*275* drm_for_each_fb - iterate over all framebuffers276* @fb: the loop cursor277* @dev: the DRM device278*279* Iterate over all framebuffers of @dev. User must hold280* &drm_mode_config.fb_lock.281*/282#define drm_for_each_fb(fb, dev) \283for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \284fb = list_first_entry(&(dev)->mode_config.fb_list, \285struct drm_framebuffer, head); \286&fb->head != (&(dev)->mode_config.fb_list); \287fb = list_next_entry(fb, head))288289/**290* struct drm_afbc_framebuffer - a special afbc frame buffer object291*292* A derived class of struct drm_framebuffer, dedicated for afbc use cases.293*/294struct drm_afbc_framebuffer {295/**296* @base: base framebuffer structure.297*/298struct drm_framebuffer base;299/**300* @block_width: width of a single afbc block301*/302u32 block_width;303/**304* @block_height: height of a single afbc block305*/306u32 block_height;307/**308* @aligned_width: aligned frame buffer width309*/310u32 aligned_width;311/**312* @aligned_height: aligned frame buffer height313*/314u32 aligned_height;315/**316* @offset: offset of the first afbc header317*/318u32 offset;319/**320* @afbc_size: minimum size of afbc buffer321*/322u32 afbc_size;323};324325#define fb_to_afbc_fb(x) container_of(x, struct drm_afbc_framebuffer, base)326327#endif328329330