17520a277SDaniel Vetter /* 27520a277SDaniel Vetter * Copyright (c) 2016 Intel Corporation 37520a277SDaniel Vetter * 47520a277SDaniel Vetter * Permission to use, copy, modify, distribute, and sell this software and its 57520a277SDaniel Vetter * documentation for any purpose is hereby granted without fee, provided that 67520a277SDaniel Vetter * the above copyright notice appear in all copies and that both that copyright 77520a277SDaniel Vetter * notice and this permission notice appear in supporting documentation, and 87520a277SDaniel Vetter * that the name of the copyright holders not be used in advertising or 97520a277SDaniel Vetter * publicity pertaining to distribution of the software without specific, 107520a277SDaniel Vetter * written prior permission. The copyright holders make no representations 117520a277SDaniel Vetter * about the suitability of this software for any purpose. It is provided "as 127520a277SDaniel Vetter * is" without express or implied warranty. 137520a277SDaniel Vetter * 147520a277SDaniel Vetter * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 157520a277SDaniel Vetter * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 167520a277SDaniel Vetter * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 177520a277SDaniel Vetter * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 187520a277SDaniel Vetter * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 197520a277SDaniel Vetter * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 207520a277SDaniel Vetter * OF THIS SOFTWARE. 217520a277SDaniel Vetter */ 227520a277SDaniel Vetter 237520a277SDaniel Vetter #ifndef __DRM_FRAMEBUFFER_H__ 247520a277SDaniel Vetter #define __DRM_FRAMEBUFFER_H__ 257520a277SDaniel Vetter 267520a277SDaniel Vetter #include <linux/ctype.h> 272513147dSSam Ravnborg #include <linux/list.h> 282513147dSSam Ravnborg #include <linux/sched.h> 292513147dSSam Ravnborg 30949619f3SDaniel Vetter #include <drm/drm_mode_object.h> 317520a277SDaniel Vetter 322513147dSSam Ravnborg struct drm_clip_rect; 337520a277SDaniel Vetter struct drm_device; 342513147dSSam Ravnborg struct drm_file; 352513147dSSam Ravnborg struct drm_framebuffer; 362513147dSSam Ravnborg struct drm_gem_object; 377520a277SDaniel Vetter 387520a277SDaniel Vetter /** 397520a277SDaniel Vetter * struct drm_framebuffer_funcs - framebuffer hooks 407520a277SDaniel Vetter */ 417520a277SDaniel Vetter struct drm_framebuffer_funcs { 427520a277SDaniel Vetter /** 437520a277SDaniel Vetter * @destroy: 447520a277SDaniel Vetter * 457520a277SDaniel Vetter * Clean up framebuffer resources, specifically also unreference the 467520a277SDaniel Vetter * backing storage. The core guarantees to call this function for every 47d574528aSDaniel Vetter * framebuffer successfully created by calling 48d574528aSDaniel Vetter * &drm_mode_config_funcs.fb_create. Drivers must also call 497520a277SDaniel Vetter * drm_framebuffer_cleanup() to release DRM core resources for this 507520a277SDaniel Vetter * framebuffer. 517520a277SDaniel Vetter */ 527520a277SDaniel Vetter void (*destroy)(struct drm_framebuffer *framebuffer); 537520a277SDaniel Vetter 547520a277SDaniel Vetter /** 557520a277SDaniel Vetter * @create_handle: 567520a277SDaniel Vetter * 577520a277SDaniel Vetter * Create a buffer handle in the driver-specific buffer manager (either 58ea0dd85aSDaniel Vetter * GEM or TTM) valid for the passed-in &struct drm_file. This is used by 597520a277SDaniel Vetter * the core to implement the GETFB IOCTL, which returns (for 607520a277SDaniel Vetter * sufficiently priviledged user) also a native buffer handle. This can 617520a277SDaniel Vetter * be used for seamless transitions between modesetting clients by 627520a277SDaniel Vetter * copying the current screen contents to a private buffer and blending 637520a277SDaniel Vetter * between that and the new contents. 647520a277SDaniel Vetter * 657520a277SDaniel Vetter * GEM based drivers should call drm_gem_handle_create() to create the 667520a277SDaniel Vetter * handle. 677520a277SDaniel Vetter * 687520a277SDaniel Vetter * RETURNS: 697520a277SDaniel Vetter * 707520a277SDaniel Vetter * 0 on success or a negative error code on failure. 717520a277SDaniel Vetter */ 727520a277SDaniel Vetter int (*create_handle)(struct drm_framebuffer *fb, 737520a277SDaniel Vetter struct drm_file *file_priv, 747520a277SDaniel Vetter unsigned int *handle); 757520a277SDaniel Vetter /** 767520a277SDaniel Vetter * @dirty: 777520a277SDaniel Vetter * 787520a277SDaniel Vetter * Optional callback for the dirty fb IOCTL. 797520a277SDaniel Vetter * 807520a277SDaniel Vetter * Userspace can notify the driver via this callback that an area of the 817520a277SDaniel Vetter * framebuffer has changed and should be flushed to the display 827520a277SDaniel Vetter * hardware. This can also be used internally, e.g. by the fbdev 837520a277SDaniel Vetter * emulation, though that's not the case currently. 847520a277SDaniel Vetter * 857520a277SDaniel Vetter * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd 867520a277SDaniel Vetter * for more information as all the semantics and arguments have a one to 877520a277SDaniel Vetter * one mapping on this function. 887520a277SDaniel Vetter * 897520a277SDaniel Vetter * RETURNS: 907520a277SDaniel Vetter * 917520a277SDaniel Vetter * 0 on success or a negative error code on failure. 927520a277SDaniel Vetter */ 937520a277SDaniel Vetter int (*dirty)(struct drm_framebuffer *framebuffer, 947520a277SDaniel Vetter struct drm_file *file_priv, unsigned flags, 957520a277SDaniel Vetter unsigned color, struct drm_clip_rect *clips, 967520a277SDaniel Vetter unsigned num_clips); 977520a277SDaniel Vetter }; 987520a277SDaniel Vetter 99750fb8c4SDaniel Vetter /** 100750fb8c4SDaniel Vetter * struct drm_framebuffer - frame buffer object 101750fb8c4SDaniel Vetter * 1027520a277SDaniel Vetter * Note that the fb is refcounted for the benefit of driver internals, 1037520a277SDaniel Vetter * for example some hw, disabling a CRTC/plane is asynchronous, and 1047520a277SDaniel Vetter * scanout does not actually complete until the next vblank. So some 1057520a277SDaniel Vetter * cleanup (like releasing the reference(s) on the backing GEM bo(s)) 1067520a277SDaniel Vetter * should be deferred. In cases like this, the driver would like to 1077520a277SDaniel Vetter * hold a ref to the fb even though it has already been removed from 108a4a69da0SThierry Reding * userspace perspective. See drm_framebuffer_get() and 109a4a69da0SThierry Reding * drm_framebuffer_put(). 110750fb8c4SDaniel Vetter * 111750fb8c4SDaniel Vetter * The refcount is stored inside the mode object @base. 1127520a277SDaniel Vetter */ 113750fb8c4SDaniel Vetter struct drm_framebuffer { 114750fb8c4SDaniel Vetter /** 115750fb8c4SDaniel Vetter * @dev: DRM device this framebuffer belongs to 116750fb8c4SDaniel Vetter */ 117750fb8c4SDaniel Vetter struct drm_device *dev; 118750fb8c4SDaniel Vetter /** 119d574528aSDaniel Vetter * @head: Place on the &drm_mode_config.fb_list, access protected by 120d574528aSDaniel Vetter * &drm_mode_config.fb_lock. 1217520a277SDaniel Vetter */ 1227520a277SDaniel Vetter struct list_head head; 123750fb8c4SDaniel Vetter 124750fb8c4SDaniel Vetter /** 125750fb8c4SDaniel Vetter * @base: base modeset object structure, contains the reference count. 126750fb8c4SDaniel Vetter */ 1277520a277SDaniel Vetter struct drm_mode_object base; 1288d44e9e6SMaarten Lankhorst 1298d44e9e6SMaarten Lankhorst /** 1308d44e9e6SMaarten Lankhorst * @comm: Name of the process allocating the fb, used for fb dumping. 1318d44e9e6SMaarten Lankhorst */ 1328d44e9e6SMaarten Lankhorst char comm[TASK_COMM_LEN]; 1338d44e9e6SMaarten Lankhorst 134750fb8c4SDaniel Vetter /** 135e14c23c6SVille Syrjälä * @format: framebuffer format information 136e14c23c6SVille Syrjälä */ 137e14c23c6SVille Syrjälä const struct drm_format_info *format; 138e14c23c6SVille Syrjälä /** 139750fb8c4SDaniel Vetter * @funcs: framebuffer vfunc table 140750fb8c4SDaniel Vetter */ 1417520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs; 142750fb8c4SDaniel Vetter /** 143750fb8c4SDaniel Vetter * @pitches: Line stride per buffer. For userspace created object this 144750fb8c4SDaniel Vetter * is copied from drm_mode_fb_cmd2. 145750fb8c4SDaniel Vetter */ 1467520a277SDaniel Vetter unsigned int pitches[4]; 147750fb8c4SDaniel Vetter /** 148750fb8c4SDaniel Vetter * @offsets: Offset from buffer start to the actual pixel data in bytes, 149750fb8c4SDaniel Vetter * per buffer. For userspace created object this is copied from 150750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 151750fb8c4SDaniel Vetter * 152750fb8c4SDaniel Vetter * Note that this is a linear offset and does not take into account 153750fb8c4SDaniel Vetter * tiling or buffer laytou per @modifier. It meant to be used when the 154750fb8c4SDaniel Vetter * actual pixel data for this framebuffer plane starts at an offset, 155750fb8c4SDaniel Vetter * e.g. when multiple planes are allocated within the same backing 156750fb8c4SDaniel Vetter * storage buffer object. For tiled layouts this generally means it 157750fb8c4SDaniel Vetter * @offsets must at least be tile-size aligned, but hardware often has 158750fb8c4SDaniel Vetter * stricter requirements. 159750fb8c4SDaniel Vetter * 160750fb8c4SDaniel Vetter * This should not be used to specifiy x/y pixel offsets into the buffer 161750fb8c4SDaniel Vetter * data (even for linear buffers). Specifying an x/y pixel offset is 162ea0dd85aSDaniel Vetter * instead done through the source rectangle in &struct drm_plane_state. 163750fb8c4SDaniel Vetter */ 1647520a277SDaniel Vetter unsigned int offsets[4]; 165750fb8c4SDaniel Vetter /** 166bae781b2SVille Syrjälä * @modifier: Data layout modifier. This is used to describe 167750fb8c4SDaniel Vetter * tiling, or also special layouts (like compression) of auxiliary 168750fb8c4SDaniel Vetter * buffers. For userspace created object this is copied from 169750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 170750fb8c4SDaniel Vetter */ 171bae781b2SVille Syrjälä uint64_t modifier; 172750fb8c4SDaniel Vetter /** 173750fb8c4SDaniel Vetter * @width: Logical width of the visible area of the framebuffer, in 174750fb8c4SDaniel Vetter * pixels. 175750fb8c4SDaniel Vetter */ 1767520a277SDaniel Vetter unsigned int width; 177750fb8c4SDaniel Vetter /** 178750fb8c4SDaniel Vetter * @height: Logical height of the visible area of the framebuffer, in 179750fb8c4SDaniel Vetter * pixels. 180750fb8c4SDaniel Vetter */ 1817520a277SDaniel Vetter unsigned int height; 182750fb8c4SDaniel Vetter /** 183750fb8c4SDaniel Vetter * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or 184750fb8c4SDaniel Vetter * DRM_MODE_FB_MODIFIERS. 185750fb8c4SDaniel Vetter */ 1867520a277SDaniel Vetter int flags; 187750fb8c4SDaniel Vetter /** 188750fb8c4SDaniel Vetter * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor 189750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 190750fb8c4SDaniel Vetter * universal plane. 191750fb8c4SDaniel Vetter */ 1927520a277SDaniel Vetter int hot_x; 193750fb8c4SDaniel Vetter /** 194750fb8c4SDaniel Vetter * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor 195750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 196750fb8c4SDaniel Vetter * universal plane. 197750fb8c4SDaniel Vetter */ 1987520a277SDaniel Vetter int hot_y; 199750fb8c4SDaniel Vetter /** 200d574528aSDaniel Vetter * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock. 201750fb8c4SDaniel Vetter */ 2027520a277SDaniel Vetter struct list_head filp_head; 2034c3dbb2cSNoralf Trønnes /** 2044c3dbb2cSNoralf Trønnes * @obj: GEM objects backing the framebuffer, one per plane (optional). 2054c3dbb2cSNoralf Trønnes * 2064c3dbb2cSNoralf Trønnes * This is used by the GEM framebuffer helpers, see e.g. 2074c3dbb2cSNoralf Trønnes * drm_gem_fb_create(). 2084c3dbb2cSNoralf Trønnes */ 2094c3dbb2cSNoralf Trønnes struct drm_gem_object *obj[4]; 2107520a277SDaniel Vetter }; 2117520a277SDaniel Vetter 212afb21ea6SDaniel Vetter #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) 213afb21ea6SDaniel Vetter 2147520a277SDaniel Vetter int drm_framebuffer_init(struct drm_device *dev, 2157520a277SDaniel Vetter struct drm_framebuffer *fb, 2167520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs); 2177520a277SDaniel Vetter struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 218418da172SKeith Packard struct drm_file *file_priv, 2197520a277SDaniel Vetter uint32_t id); 2207520a277SDaniel Vetter void drm_framebuffer_remove(struct drm_framebuffer *fb); 2217520a277SDaniel Vetter void drm_framebuffer_cleanup(struct drm_framebuffer *fb); 2227520a277SDaniel Vetter void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); 2237520a277SDaniel Vetter 2247520a277SDaniel Vetter /** 225a4a69da0SThierry Reding * drm_framebuffer_get - acquire a framebuffer reference 226a4a69da0SThierry Reding * @fb: DRM framebuffer 2277520a277SDaniel Vetter * 228a4a69da0SThierry Reding * This function increments the framebuffer's reference count. 2297520a277SDaniel Vetter */ 230a4a69da0SThierry Reding static inline void drm_framebuffer_get(struct drm_framebuffer *fb) 2317520a277SDaniel Vetter { 232a4a69da0SThierry Reding drm_mode_object_get(&fb->base); 2337520a277SDaniel Vetter } 2347520a277SDaniel Vetter 2357520a277SDaniel Vetter /** 236a4a69da0SThierry Reding * drm_framebuffer_put - release a framebuffer reference 237a4a69da0SThierry Reding * @fb: DRM framebuffer 2387520a277SDaniel Vetter * 239a4a69da0SThierry Reding * This function decrements the framebuffer's reference count and frees the 240a4a69da0SThierry Reding * framebuffer if the reference count drops to zero. 241a4a69da0SThierry Reding */ 242a4a69da0SThierry Reding static inline void drm_framebuffer_put(struct drm_framebuffer *fb) 243a4a69da0SThierry Reding { 244a4a69da0SThierry Reding drm_mode_object_put(&fb->base); 245a4a69da0SThierry Reding } 246a4a69da0SThierry Reding 247a4a69da0SThierry Reding /** 2487520a277SDaniel Vetter * drm_framebuffer_read_refcount - read the framebuffer reference count. 2497520a277SDaniel Vetter * @fb: framebuffer 2507520a277SDaniel Vetter * 2517520a277SDaniel Vetter * This functions returns the framebuffer's reference count. 2527520a277SDaniel Vetter */ 2536ff1086eSNoralf Trønnes static inline uint32_t drm_framebuffer_read_refcount(const struct drm_framebuffer *fb) 2547520a277SDaniel Vetter { 2552c935bc5SPeter Zijlstra return kref_read(&fb->base.refcount); 2567520a277SDaniel Vetter } 257afb21ea6SDaniel Vetter 258afb21ea6SDaniel Vetter /** 259389f78b3SChris Wilson * drm_framebuffer_assign - store a reference to the fb 260389f78b3SChris Wilson * @p: location to store framebuffer 261389f78b3SChris Wilson * @fb: new framebuffer (maybe NULL) 262389f78b3SChris Wilson * 263389f78b3SChris Wilson * This functions sets the location to store a reference to the framebuffer, 264389f78b3SChris Wilson * unreferencing the framebuffer that was previously stored in that location. 265389f78b3SChris Wilson */ 266389f78b3SChris Wilson static inline void drm_framebuffer_assign(struct drm_framebuffer **p, 267389f78b3SChris Wilson struct drm_framebuffer *fb) 268389f78b3SChris Wilson { 269389f78b3SChris Wilson if (fb) 270a4a69da0SThierry Reding drm_framebuffer_get(fb); 271389f78b3SChris Wilson if (*p) 272a4a69da0SThierry Reding drm_framebuffer_put(*p); 273389f78b3SChris Wilson *p = fb; 274389f78b3SChris Wilson } 275389f78b3SChris Wilson 276389f78b3SChris Wilson /* 277afb21ea6SDaniel Vetter * drm_for_each_fb - iterate over all framebuffers 278afb21ea6SDaniel Vetter * @fb: the loop cursor 279afb21ea6SDaniel Vetter * @dev: the DRM device 280afb21ea6SDaniel Vetter * 281d574528aSDaniel Vetter * Iterate over all framebuffers of @dev. User must hold 282d574528aSDaniel Vetter * &drm_mode_config.fb_lock. 283afb21ea6SDaniel Vetter */ 284afb21ea6SDaniel Vetter #define drm_for_each_fb(fb, dev) \ 285afb21ea6SDaniel Vetter for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ 286afb21ea6SDaniel Vetter fb = list_first_entry(&(dev)->mode_config.fb_list, \ 287afb21ea6SDaniel Vetter struct drm_framebuffer, head); \ 288afb21ea6SDaniel Vetter &fb->head != (&(dev)->mode_config.fb_list); \ 289afb21ea6SDaniel Vetter fb = list_next_entry(fb, head)) 2908f8f6a6cSVille Syrjälä 2918f8f6a6cSVille Syrjälä int drm_framebuffer_plane_width(int width, 2928f8f6a6cSVille Syrjälä const struct drm_framebuffer *fb, int plane); 2938f8f6a6cSVille Syrjälä int drm_framebuffer_plane_height(int height, 2948f8f6a6cSVille Syrjälä const struct drm_framebuffer *fb, int plane); 2958f8f6a6cSVille Syrjälä 2967520a277SDaniel Vetter #endif 297