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 437520a277SDaniel Vetter * framebuffer successfully created by ->fb_create() in 447520a277SDaniel Vetter * &drm_mode_config_funcs. 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 547520a277SDaniel 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 104750fb8c4SDaniel Vetter * userspace perspective. See drm_framebuffer_reference() and 105750fb8c4SDaniel Vetter * drm_framebuffer_unreference(). 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 /** 115750fb8c4SDaniel Vetter * @head: Place on the dev->mode_config.fb_list, access protected by 1167520a277SDaniel Vetter * dev->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 /** 125750fb8c4SDaniel Vetter * @funcs: framebuffer vfunc table 126750fb8c4SDaniel Vetter */ 1277520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs; 128750fb8c4SDaniel Vetter /** 129750fb8c4SDaniel Vetter * @pitches: Line stride per buffer. For userspace created object this 130750fb8c4SDaniel Vetter * is copied from drm_mode_fb_cmd2. 131750fb8c4SDaniel Vetter */ 1327520a277SDaniel Vetter unsigned int pitches[4]; 133750fb8c4SDaniel Vetter /** 134750fb8c4SDaniel Vetter * @offsets: Offset from buffer start to the actual pixel data in bytes, 135750fb8c4SDaniel Vetter * per buffer. For userspace created object this is copied from 136750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 137750fb8c4SDaniel Vetter * 138750fb8c4SDaniel Vetter * Note that this is a linear offset and does not take into account 139750fb8c4SDaniel Vetter * tiling or buffer laytou per @modifier. It meant to be used when the 140750fb8c4SDaniel Vetter * actual pixel data for this framebuffer plane starts at an offset, 141750fb8c4SDaniel Vetter * e.g. when multiple planes are allocated within the same backing 142750fb8c4SDaniel Vetter * storage buffer object. For tiled layouts this generally means it 143750fb8c4SDaniel Vetter * @offsets must at least be tile-size aligned, but hardware often has 144750fb8c4SDaniel Vetter * stricter requirements. 145750fb8c4SDaniel Vetter * 146750fb8c4SDaniel Vetter * This should not be used to specifiy x/y pixel offsets into the buffer 147750fb8c4SDaniel Vetter * data (even for linear buffers). Specifying an x/y pixel offset is 148750fb8c4SDaniel Vetter * instead done through the source rectangle in struct &drm_plane_state. 149750fb8c4SDaniel Vetter */ 1507520a277SDaniel Vetter unsigned int offsets[4]; 151750fb8c4SDaniel Vetter /** 152bae781b2SVille Syrjälä * @modifier: Data layout modifier. This is used to describe 153750fb8c4SDaniel Vetter * tiling, or also special layouts (like compression) of auxiliary 154750fb8c4SDaniel Vetter * buffers. For userspace created object this is copied from 155750fb8c4SDaniel Vetter * drm_mode_fb_cmd2. 156750fb8c4SDaniel Vetter */ 157bae781b2SVille Syrjälä uint64_t modifier; 158750fb8c4SDaniel Vetter /** 159750fb8c4SDaniel Vetter * @width: Logical width of the visible area of the framebuffer, in 160750fb8c4SDaniel Vetter * pixels. 161750fb8c4SDaniel Vetter */ 1627520a277SDaniel Vetter unsigned int width; 163750fb8c4SDaniel Vetter /** 164750fb8c4SDaniel Vetter * @height: Logical height of the visible area of the framebuffer, in 165750fb8c4SDaniel Vetter * pixels. 166750fb8c4SDaniel Vetter */ 1677520a277SDaniel Vetter unsigned int height; 168750fb8c4SDaniel Vetter /** 169750fb8c4SDaniel Vetter * @depth: Depth in bits per pixel for RGB formats. 0 for everything 170750fb8c4SDaniel Vetter * else. Legacy information derived from @pixel_format, it's suggested to use 171750fb8c4SDaniel Vetter * the DRM FOURCC codes and helper functions directly instead. 172750fb8c4SDaniel Vetter */ 1737520a277SDaniel Vetter unsigned int depth; 174750fb8c4SDaniel Vetter /** 175750fb8c4SDaniel Vetter * @bits_per_pixel: Storage used bits per pixel for RGB formats. 0 for 176750fb8c4SDaniel Vetter * everything else. Legacy information derived from @pixel_format, it's 177750fb8c4SDaniel Vetter * suggested to use the DRM FOURCC codes and helper functions directly 178750fb8c4SDaniel Vetter * instead. 179750fb8c4SDaniel Vetter */ 1807520a277SDaniel Vetter int bits_per_pixel; 181750fb8c4SDaniel Vetter /** 182750fb8c4SDaniel Vetter * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or 183750fb8c4SDaniel Vetter * DRM_MODE_FB_MODIFIERS. 184750fb8c4SDaniel Vetter */ 1857520a277SDaniel Vetter int flags; 186750fb8c4SDaniel Vetter /** 187750fb8c4SDaniel Vetter * @pixel_format: DRM FOURCC code describing the pixel format. 188750fb8c4SDaniel Vetter */ 1897520a277SDaniel Vetter uint32_t pixel_format; /* fourcc format */ 190750fb8c4SDaniel Vetter /** 191750fb8c4SDaniel Vetter * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor 192750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 193750fb8c4SDaniel Vetter * universal plane. 194750fb8c4SDaniel Vetter */ 1957520a277SDaniel Vetter int hot_x; 196750fb8c4SDaniel Vetter /** 197750fb8c4SDaniel Vetter * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor 198750fb8c4SDaniel Vetter * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 199750fb8c4SDaniel Vetter * universal plane. 200750fb8c4SDaniel Vetter */ 2017520a277SDaniel Vetter int hot_y; 202750fb8c4SDaniel Vetter /** 203750fb8c4SDaniel Vetter * @filp_head: Placed on struct &drm_file fbs list_head, protected by 204750fb8c4SDaniel Vetter * fbs_lock in the same structure. 205750fb8c4SDaniel Vetter */ 2067520a277SDaniel Vetter struct list_head filp_head; 2077520a277SDaniel Vetter }; 2087520a277SDaniel Vetter 209afb21ea6SDaniel Vetter #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) 210afb21ea6SDaniel Vetter 2117520a277SDaniel Vetter int drm_framebuffer_init(struct drm_device *dev, 2127520a277SDaniel Vetter struct drm_framebuffer *fb, 2137520a277SDaniel Vetter const struct drm_framebuffer_funcs *funcs); 2147520a277SDaniel Vetter struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 2157520a277SDaniel Vetter uint32_t id); 2167520a277SDaniel Vetter void drm_framebuffer_remove(struct drm_framebuffer *fb); 2177520a277SDaniel Vetter void drm_framebuffer_cleanup(struct drm_framebuffer *fb); 2187520a277SDaniel Vetter void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); 2197520a277SDaniel Vetter 2207520a277SDaniel Vetter /** 2217520a277SDaniel Vetter * drm_framebuffer_reference - incr the fb refcnt 2227520a277SDaniel Vetter * @fb: framebuffer 2237520a277SDaniel Vetter * 2247520a277SDaniel Vetter * This functions increments the fb's refcount. 2257520a277SDaniel Vetter */ 2267520a277SDaniel Vetter static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) 2277520a277SDaniel Vetter { 2287520a277SDaniel Vetter drm_mode_object_reference(&fb->base); 2297520a277SDaniel Vetter } 2307520a277SDaniel Vetter 2317520a277SDaniel Vetter /** 2327520a277SDaniel Vetter * drm_framebuffer_unreference - unref a framebuffer 2337520a277SDaniel Vetter * @fb: framebuffer to unref 2347520a277SDaniel Vetter * 2357520a277SDaniel Vetter * This functions decrements the fb's refcount and frees it if it drops to zero. 2367520a277SDaniel Vetter */ 2377520a277SDaniel Vetter static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) 2387520a277SDaniel Vetter { 2397520a277SDaniel Vetter drm_mode_object_unreference(&fb->base); 2407520a277SDaniel Vetter } 2417520a277SDaniel Vetter 2427520a277SDaniel Vetter /** 2437520a277SDaniel Vetter * drm_framebuffer_read_refcount - read the framebuffer reference count. 2447520a277SDaniel Vetter * @fb: framebuffer 2457520a277SDaniel Vetter * 2467520a277SDaniel Vetter * This functions returns the framebuffer's reference count. 2477520a277SDaniel Vetter */ 2487520a277SDaniel Vetter static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) 2497520a277SDaniel Vetter { 2502c935bc5SPeter Zijlstra return kref_read(&fb->base.refcount); 2517520a277SDaniel Vetter } 252afb21ea6SDaniel Vetter 253afb21ea6SDaniel Vetter /** 254389f78b3SChris Wilson * drm_framebuffer_assign - store a reference to the fb 255389f78b3SChris Wilson * @p: location to store framebuffer 256389f78b3SChris Wilson * @fb: new framebuffer (maybe NULL) 257389f78b3SChris Wilson * 258389f78b3SChris Wilson * This functions sets the location to store a reference to the framebuffer, 259389f78b3SChris Wilson * unreferencing the framebuffer that was previously stored in that location. 260389f78b3SChris Wilson */ 261389f78b3SChris Wilson static inline void drm_framebuffer_assign(struct drm_framebuffer **p, 262389f78b3SChris Wilson struct drm_framebuffer *fb) 263389f78b3SChris Wilson { 264389f78b3SChris Wilson if (fb) 265389f78b3SChris Wilson drm_framebuffer_reference(fb); 266389f78b3SChris Wilson if (*p) 267389f78b3SChris Wilson drm_framebuffer_unreference(*p); 268389f78b3SChris Wilson *p = fb; 269389f78b3SChris Wilson } 270389f78b3SChris Wilson 271389f78b3SChris Wilson /* 272afb21ea6SDaniel Vetter * drm_for_each_fb - iterate over all framebuffers 273afb21ea6SDaniel Vetter * @fb: the loop cursor 274afb21ea6SDaniel Vetter * @dev: the DRM device 275afb21ea6SDaniel Vetter * 276afb21ea6SDaniel Vetter * Iterate over all framebuffers of @dev. User must hold the fb_lock from 277afb21ea6SDaniel Vetter * &drm_mode_config. 278afb21ea6SDaniel Vetter */ 279afb21ea6SDaniel Vetter #define drm_for_each_fb(fb, dev) \ 280afb21ea6SDaniel Vetter for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ 281afb21ea6SDaniel Vetter fb = list_first_entry(&(dev)->mode_config.fb_list, \ 282afb21ea6SDaniel Vetter struct drm_framebuffer, head); \ 283afb21ea6SDaniel Vetter &fb->head != (&(dev)->mode_config.fb_list); \ 284afb21ea6SDaniel Vetter fb = list_next_entry(fb, head)) 2857520a277SDaniel Vetter #endif 286