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/list.h> 277520a277SDaniel Vetter #include <linux/ctype.h> 28949619f3SDaniel Vetter #include <drm/drm_mode_object.h> 297520a277SDaniel Vetter 307520a277SDaniel Vetter struct drm_framebuffer; 317520a277SDaniel Vetter struct drm_file; 327520a277SDaniel Vetter struct drm_device; 337520a277SDaniel Vetter 347520a277SDaniel Vetter /** 357520a277SDaniel Vetter * struct drm_framebuffer_funcs - framebuffer hooks 367520a277SDaniel Vetter */ 377520a277SDaniel Vetter struct drm_framebuffer_funcs { 387520a277SDaniel Vetter /** 397520a277SDaniel Vetter * @destroy: 407520a277SDaniel Vetter * 417520a277SDaniel Vetter * Clean up framebuffer resources, specifically also unreference the 427520a277SDaniel Vetter * backing storage. The core guarantees to call this function for every 43d574528aSDaniel Vetter * framebuffer successfully created by calling 44d574528aSDaniel Vetter * &drm_mode_config_funcs.fb_create. Drivers must also call 457520a277SDaniel Vetter * drm_framebuffer_cleanup() to release DRM core resources for this 467520a277SDaniel Vetter * framebuffer. 477520a277SDaniel Vetter */ 487520a277SDaniel Vetter void (*destroy)(struct drm_framebuffer *framebuffer); 497520a277SDaniel Vetter 507520a277SDaniel Vetter /** 517520a277SDaniel Vetter * @create_handle: 527520a277SDaniel Vetter * 537520a277SDaniel Vetter * Create a buffer handle in the driver-specific buffer manager (either 54ea0dd85aSDaniel Vetter * GEM or TTM) valid for the passed-in &struct drm_file. This is used by 557520a277SDaniel Vetter * the core to implement the GETFB IOCTL, which returns (for 567520a277SDaniel Vetter * sufficiently priviledged user) also a native buffer handle. This can 577520a277SDaniel Vetter * be used for seamless transitions between modesetting clients by 587520a277SDaniel Vetter * copying the current screen contents to a private buffer and blending 597520a277SDaniel Vetter * between that and the new contents. 607520a277SDaniel Vetter * 617520a277SDaniel Vetter * GEM based drivers should call drm_gem_handle_create() to create the 627520a277SDaniel Vetter * handle. 637520a277SDaniel Vetter * 647520a277SDaniel Vetter * RETURNS: 657520a277SDaniel Vetter * 667520a277SDaniel Vetter * 0 on success or a negative error code on failure. 677520a277SDaniel Vetter */ 687520a277SDaniel Vetter int (*create_handle)(struct drm_framebuffer *fb, 697520a277SDaniel Vetter struct drm_file *file_priv, 707520a277SDaniel Vetter unsigned int *handle); 717520a277SDaniel Vetter /** 727520a277SDaniel Vetter * @dirty: 737520a277SDaniel Vetter * 747520a277SDaniel Vetter * Optional callback for the dirty fb IOCTL. 757520a277SDaniel Vetter * 767520a277SDaniel Vetter * Userspace can notify the driver via this callback that an area of the 777520a277SDaniel Vetter * framebuffer has changed and should be flushed to the display 787520a277SDaniel Vetter * hardware. This can also be used internally, e.g. by the fbdev 797520a277SDaniel Vetter * emulation, though that's not the case currently. 807520a277SDaniel Vetter * 817520a277SDaniel Vetter * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd 827520a277SDaniel Vetter * for more information as all the semantics and arguments have a one to 837520a277SDaniel Vetter * one mapping on this function. 847520a277SDaniel Vetter * 857520a277SDaniel Vetter * RETURNS: 867520a277SDaniel Vetter * 877520a277SDaniel Vetter * 0 on success or a negative error code on failure. 887520a277SDaniel Vetter */ 897520a277SDaniel Vetter int (*dirty)(struct drm_framebuffer *framebuffer, 907520a277SDaniel Vetter struct drm_file *file_priv, unsigned flags, 917520a277SDaniel Vetter unsigned color, struct drm_clip_rect *clips, 927520a277SDaniel Vetter unsigned num_clips); 937520a277SDaniel Vetter }; 947520a277SDaniel Vetter 95750fb8c4SDaniel Vetter /** 96750fb8c4SDaniel Vetter * struct drm_framebuffer - frame buffer object 97750fb8c4SDaniel Vetter * 987520a277SDaniel Vetter * Note that the fb is refcounted for the benefit of driver internals, 997520a277SDaniel Vetter * for example some hw, disabling a CRTC/plane is asynchronous, and 1007520a277SDaniel Vetter * scanout does not actually complete until the next vblank. So some 1017520a277SDaniel Vetter * cleanup (like releasing the reference(s) on the backing GEM bo(s)) 1027520a277SDaniel Vetter * should be deferred. In cases like this, the driver would like to 1037520a277SDaniel Vetter * hold a ref to the fb even though it has already been removed from 104a4a69da0SThierry Reding * userspace perspective. See drm_framebuffer_get() and 105a4a69da0SThierry Reding * drm_framebuffer_put(). 106750fb8c4SDaniel Vetter * 107750fb8c4SDaniel Vetter * The refcount is stored inside the mode object @base. 1087520a277SDaniel Vetter */ 109750fb8c4SDaniel Vetter struct drm_framebuffer { 110750fb8c4SDaniel Vetter /** 111750fb8c4SDaniel Vetter * @dev: DRM device this framebuffer belongs to 112750fb8c4SDaniel Vetter */ 113750fb8c4SDaniel Vetter struct drm_device *dev; 114750fb8c4SDaniel Vetter /** 115d574528aSDaniel Vetter * @head: Place on the &drm_mode_config.fb_list, access protected by 116d574528aSDaniel Vetter * &drm_mode_config.fb_lock. 1177520a277SDaniel Vetter */ 1187520a277SDaniel Vetter struct list_head head; 119750fb8c4SDaniel Vetter 120750fb8c4SDaniel Vetter /** 121750fb8c4SDaniel Vetter * @base: base modeset object structure, contains the reference count. 122750fb8c4SDaniel Vetter */ 1237520a277SDaniel Vetter struct drm_mode_object base; 124750fb8c4SDaniel Vetter /** 125e14c23c6SVille Syrjälä * @format: framebuffer format information 126e14c23c6SVille Syrjälä */ 127e14c23c6SVille Syrjälä const struct drm_format_info *format; 128e14c23c6SVille Syrjälä /** 129750fb8c4SDaniel Vetter * @funcs: framebuffer vfunc table 130750fb8c4SDaniel Vetter */ 1317520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs; 132750fb8c4SDaniel Vetter /** 133750fb8c4SDaniel Vetter * @pitches: Line stride per buffer. For userspace created object this 134750fb8c4SDaniel Vetter * is copied from drm_mode_fb_cmd2. 135750fb8c4SDaniel Vetter */ 1367520a277SDaniel Vetter unsigned int pitches[4]; 137750fb8c4SDaniel Vetter /** 138750fb8c4SDaniel Vetter * @offsets: Offset from buffer start to the actual pixel data in bytes, 139750fb8c4SDaniel Vetter * per buffer. For userspace created object this is copied from 140750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 141750fb8c4SDaniel Vetter * 142750fb8c4SDaniel Vetter * Note that this is a linear offset and does not take into account 143750fb8c4SDaniel Vetter * tiling or buffer laytou per @modifier. It meant to be used when the 144750fb8c4SDaniel Vetter * actual pixel data for this framebuffer plane starts at an offset, 145750fb8c4SDaniel Vetter * e.g. when multiple planes are allocated within the same backing 146750fb8c4SDaniel Vetter * storage buffer object. For tiled layouts this generally means it 147750fb8c4SDaniel Vetter * @offsets must at least be tile-size aligned, but hardware often has 148750fb8c4SDaniel Vetter * stricter requirements. 149750fb8c4SDaniel Vetter * 150750fb8c4SDaniel Vetter * This should not be used to specifiy x/y pixel offsets into the buffer 151750fb8c4SDaniel Vetter * data (even for linear buffers). Specifying an x/y pixel offset is 152ea0dd85aSDaniel Vetter * instead done through the source rectangle in &struct drm_plane_state. 153750fb8c4SDaniel Vetter */ 1547520a277SDaniel Vetter unsigned int offsets[4]; 155750fb8c4SDaniel Vetter /** 156bae781b2SVille Syrjälä * @modifier: Data layout modifier. This is used to describe 157750fb8c4SDaniel Vetter * tiling, or also special layouts (like compression) of auxiliary 158750fb8c4SDaniel Vetter * buffers. For userspace created object this is copied from 159750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 160750fb8c4SDaniel Vetter */ 161bae781b2SVille Syrjälä uint64_t modifier; 162750fb8c4SDaniel Vetter /** 163750fb8c4SDaniel Vetter * @width: Logical width of the visible area of the framebuffer, in 164750fb8c4SDaniel Vetter * pixels. 165750fb8c4SDaniel Vetter */ 1667520a277SDaniel Vetter unsigned int width; 167750fb8c4SDaniel Vetter /** 168750fb8c4SDaniel Vetter * @height: Logical height of the visible area of the framebuffer, in 169750fb8c4SDaniel Vetter * pixels. 170750fb8c4SDaniel Vetter */ 1717520a277SDaniel Vetter unsigned int height; 172750fb8c4SDaniel Vetter /** 173750fb8c4SDaniel Vetter * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or 174750fb8c4SDaniel Vetter * DRM_MODE_FB_MODIFIERS. 175750fb8c4SDaniel Vetter */ 1767520a277SDaniel Vetter int flags; 177750fb8c4SDaniel Vetter /** 178750fb8c4SDaniel Vetter * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor 179750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 180750fb8c4SDaniel Vetter * universal plane. 181750fb8c4SDaniel Vetter */ 1827520a277SDaniel Vetter int hot_x; 183750fb8c4SDaniel Vetter /** 184750fb8c4SDaniel Vetter * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor 185750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 186750fb8c4SDaniel Vetter * universal plane. 187750fb8c4SDaniel Vetter */ 1887520a277SDaniel Vetter int hot_y; 189750fb8c4SDaniel Vetter /** 190d574528aSDaniel Vetter * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock. 191750fb8c4SDaniel Vetter */ 1927520a277SDaniel Vetter struct list_head filp_head; 1937520a277SDaniel Vetter }; 1947520a277SDaniel Vetter 195afb21ea6SDaniel Vetter #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) 196afb21ea6SDaniel Vetter 1977520a277SDaniel Vetter int drm_framebuffer_init(struct drm_device *dev, 1987520a277SDaniel Vetter struct drm_framebuffer *fb, 1997520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs); 2007520a277SDaniel Vetter struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 2017520a277SDaniel Vetter uint32_t id); 2027520a277SDaniel Vetter void drm_framebuffer_remove(struct drm_framebuffer *fb); 2037520a277SDaniel Vetter void drm_framebuffer_cleanup(struct drm_framebuffer *fb); 2047520a277SDaniel Vetter void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); 2057520a277SDaniel Vetter 2067520a277SDaniel Vetter /** 207a4a69da0SThierry Reding * drm_framebuffer_get - acquire a framebuffer reference 208a4a69da0SThierry Reding * @fb: DRM framebuffer 2097520a277SDaniel Vetter * 210a4a69da0SThierry Reding * This function increments the framebuffer's reference count. 2117520a277SDaniel Vetter */ 212a4a69da0SThierry Reding static inline void drm_framebuffer_get(struct drm_framebuffer *fb) 2137520a277SDaniel Vetter { 214a4a69da0SThierry Reding drm_mode_object_get(&fb->base); 2157520a277SDaniel Vetter } 2167520a277SDaniel Vetter 2177520a277SDaniel Vetter /** 218a4a69da0SThierry Reding * drm_framebuffer_put - release a framebuffer reference 219a4a69da0SThierry Reding * @fb: DRM framebuffer 2207520a277SDaniel Vetter * 221a4a69da0SThierry Reding * This function decrements the framebuffer's reference count and frees the 222a4a69da0SThierry Reding * framebuffer if the reference count drops to zero. 223a4a69da0SThierry Reding */ 224a4a69da0SThierry Reding static inline void drm_framebuffer_put(struct drm_framebuffer *fb) 225a4a69da0SThierry Reding { 226a4a69da0SThierry Reding drm_mode_object_put(&fb->base); 227a4a69da0SThierry Reding } 228a4a69da0SThierry Reding 229a4a69da0SThierry Reding /** 230a4a69da0SThierry Reding * drm_framebuffer_reference - acquire a framebuffer reference 231a4a69da0SThierry Reding * @fb: DRM framebuffer 232a4a69da0SThierry Reding * 233a4a69da0SThierry Reding * This is a compatibility alias for drm_framebuffer_get() and should not be 234a4a69da0SThierry Reding * used by new code. 235a4a69da0SThierry Reding */ 236a4a69da0SThierry Reding static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) 237a4a69da0SThierry Reding { 238a4a69da0SThierry Reding drm_framebuffer_get(fb); 239a4a69da0SThierry Reding } 240a4a69da0SThierry Reding 241a4a69da0SThierry Reding /** 242a4a69da0SThierry Reding * drm_framebuffer_unreference - release a framebuffer reference 243a4a69da0SThierry Reding * @fb: DRM framebuffer 244a4a69da0SThierry Reding * 245a4a69da0SThierry Reding * This is a compatibility alias for drm_framebuffer_put() and should not be 246a4a69da0SThierry Reding * used by new code. 2477520a277SDaniel Vetter */ 2487520a277SDaniel Vetter static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) 2497520a277SDaniel Vetter { 250a4a69da0SThierry Reding drm_framebuffer_put(fb); 2517520a277SDaniel Vetter } 2527520a277SDaniel Vetter 2537520a277SDaniel Vetter /** 2547520a277SDaniel Vetter * drm_framebuffer_read_refcount - read the framebuffer reference count. 2557520a277SDaniel Vetter * @fb: framebuffer 2567520a277SDaniel Vetter * 2577520a277SDaniel Vetter * This functions returns the framebuffer's reference count. 2587520a277SDaniel Vetter */ 2597520a277SDaniel Vetter static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) 2607520a277SDaniel Vetter { 2617520a277SDaniel Vetter return atomic_read(&fb->base.refcount.refcount); 2627520a277SDaniel Vetter } 263afb21ea6SDaniel Vetter 264afb21ea6SDaniel Vetter /** 265389f78b3SChris Wilson * drm_framebuffer_assign - store a reference to the fb 266389f78b3SChris Wilson * @p: location to store framebuffer 267389f78b3SChris Wilson * @fb: new framebuffer (maybe NULL) 268389f78b3SChris Wilson * 269389f78b3SChris Wilson * This functions sets the location to store a reference to the framebuffer, 270389f78b3SChris Wilson * unreferencing the framebuffer that was previously stored in that location. 271389f78b3SChris Wilson */ 272389f78b3SChris Wilson static inline void drm_framebuffer_assign(struct drm_framebuffer **p, 273389f78b3SChris Wilson struct drm_framebuffer *fb) 274389f78b3SChris Wilson { 275389f78b3SChris Wilson if (fb) 276a4a69da0SThierry Reding drm_framebuffer_get(fb); 277389f78b3SChris Wilson if (*p) 278a4a69da0SThierry Reding drm_framebuffer_put(*p); 279389f78b3SChris Wilson *p = fb; 280389f78b3SChris Wilson } 281389f78b3SChris Wilson 282389f78b3SChris Wilson /* 283afb21ea6SDaniel Vetter * drm_for_each_fb - iterate over all framebuffers 284afb21ea6SDaniel Vetter * @fb: the loop cursor 285afb21ea6SDaniel Vetter * @dev: the DRM device 286afb21ea6SDaniel Vetter * 287d574528aSDaniel Vetter * Iterate over all framebuffers of @dev. User must hold 288d574528aSDaniel Vetter * &drm_mode_config.fb_lock. 289afb21ea6SDaniel Vetter */ 290afb21ea6SDaniel Vetter #define drm_for_each_fb(fb, dev) \ 291afb21ea6SDaniel Vetter for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ 292afb21ea6SDaniel Vetter fb = list_first_entry(&(dev)->mode_config.fb_list, \ 293afb21ea6SDaniel Vetter struct drm_framebuffer, head); \ 294afb21ea6SDaniel Vetter &fb->head != (&(dev)->mode_config.fb_list); \ 295afb21ea6SDaniel Vetter fb = list_next_entry(fb, head)) 2968f8f6a6cSVille Syrjälä 2978f8f6a6cSVille Syrjälä int drm_framebuffer_plane_width(int width, 2988f8f6a6cSVille Syrjälä const struct drm_framebuffer *fb, int plane); 2998f8f6a6cSVille Syrjälä int drm_framebuffer_plane_height(int height, 3008f8f6a6cSVille Syrjälä const struct drm_framebuffer *fb, int plane); 3018f8f6a6cSVille Syrjälä 3027520a277SDaniel Vetter #endif 303