1*1dedbd3bSFrançois Tigeot /* 2*1dedbd3bSFrançois Tigeot * Copyright (c) 2016 Intel Corporation 3*1dedbd3bSFrançois Tigeot * 4*1dedbd3bSFrançois Tigeot * Permission to use, copy, modify, distribute, and sell this software and its 5*1dedbd3bSFrançois Tigeot * documentation for any purpose is hereby granted without fee, provided that 6*1dedbd3bSFrançois Tigeot * the above copyright notice appear in all copies and that both that copyright 7*1dedbd3bSFrançois Tigeot * notice and this permission notice appear in supporting documentation, and 8*1dedbd3bSFrançois Tigeot * that the name of the copyright holders not be used in advertising or 9*1dedbd3bSFrançois Tigeot * publicity pertaining to distribution of the software without specific, 10*1dedbd3bSFrançois Tigeot * written prior permission. The copyright holders make no representations 11*1dedbd3bSFrançois Tigeot * about the suitability of this software for any purpose. It is provided "as 12*1dedbd3bSFrançois Tigeot * is" without express or implied warranty. 13*1dedbd3bSFrançois Tigeot * 14*1dedbd3bSFrançois Tigeot * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15*1dedbd3bSFrançois Tigeot * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16*1dedbd3bSFrançois Tigeot * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17*1dedbd3bSFrançois Tigeot * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18*1dedbd3bSFrançois Tigeot * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19*1dedbd3bSFrançois Tigeot * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20*1dedbd3bSFrançois Tigeot * OF THIS SOFTWARE. 21*1dedbd3bSFrançois Tigeot */ 22*1dedbd3bSFrançois Tigeot 23*1dedbd3bSFrançois Tigeot #ifndef __DRM_FRAMEBUFFER_H__ 24*1dedbd3bSFrançois Tigeot #define __DRM_FRAMEBUFFER_H__ 25*1dedbd3bSFrançois Tigeot 26*1dedbd3bSFrançois Tigeot #include <linux/list.h> 27*1dedbd3bSFrançois Tigeot #include <linux/ctype.h> 28*1dedbd3bSFrançois Tigeot #include <drm/drm_mode_object.h> 29*1dedbd3bSFrançois Tigeot 30*1dedbd3bSFrançois Tigeot struct drm_framebuffer; 31*1dedbd3bSFrançois Tigeot struct drm_file; 32*1dedbd3bSFrançois Tigeot struct drm_device; 33*1dedbd3bSFrançois Tigeot 34*1dedbd3bSFrançois Tigeot /** 35*1dedbd3bSFrançois Tigeot * struct drm_framebuffer_funcs - framebuffer hooks 36*1dedbd3bSFrançois Tigeot */ 37*1dedbd3bSFrançois Tigeot struct drm_framebuffer_funcs { 38*1dedbd3bSFrançois Tigeot /** 39*1dedbd3bSFrançois Tigeot * @destroy: 40*1dedbd3bSFrançois Tigeot * 41*1dedbd3bSFrançois Tigeot * Clean up framebuffer resources, specifically also unreference the 42*1dedbd3bSFrançois Tigeot * backing storage. The core guarantees to call this function for every 43*1dedbd3bSFrançois Tigeot * framebuffer successfully created by ->fb_create() in 44*1dedbd3bSFrançois Tigeot * &drm_mode_config_funcs. Drivers must also call 45*1dedbd3bSFrançois Tigeot * drm_framebuffer_cleanup() to release DRM core resources for this 46*1dedbd3bSFrançois Tigeot * framebuffer. 47*1dedbd3bSFrançois Tigeot */ 48*1dedbd3bSFrançois Tigeot void (*destroy)(struct drm_framebuffer *framebuffer); 49*1dedbd3bSFrançois Tigeot 50*1dedbd3bSFrançois Tigeot /** 51*1dedbd3bSFrançois Tigeot * @create_handle: 52*1dedbd3bSFrançois Tigeot * 53*1dedbd3bSFrançois Tigeot * Create a buffer handle in the driver-specific buffer manager (either 54*1dedbd3bSFrançois Tigeot * GEM or TTM) valid for the passed-in struct &drm_file. This is used by 55*1dedbd3bSFrançois Tigeot * the core to implement the GETFB IOCTL, which returns (for 56*1dedbd3bSFrançois Tigeot * sufficiently priviledged user) also a native buffer handle. This can 57*1dedbd3bSFrançois Tigeot * be used for seamless transitions between modesetting clients by 58*1dedbd3bSFrançois Tigeot * copying the current screen contents to a private buffer and blending 59*1dedbd3bSFrançois Tigeot * between that and the new contents. 60*1dedbd3bSFrançois Tigeot * 61*1dedbd3bSFrançois Tigeot * GEM based drivers should call drm_gem_handle_create() to create the 62*1dedbd3bSFrançois Tigeot * handle. 63*1dedbd3bSFrançois Tigeot * 64*1dedbd3bSFrançois Tigeot * RETURNS: 65*1dedbd3bSFrançois Tigeot * 66*1dedbd3bSFrançois Tigeot * 0 on success or a negative error code on failure. 67*1dedbd3bSFrançois Tigeot */ 68*1dedbd3bSFrançois Tigeot int (*create_handle)(struct drm_framebuffer *fb, 69*1dedbd3bSFrançois Tigeot struct drm_file *file_priv, 70*1dedbd3bSFrançois Tigeot unsigned int *handle); 71*1dedbd3bSFrançois Tigeot /** 72*1dedbd3bSFrançois Tigeot * @dirty: 73*1dedbd3bSFrançois Tigeot * 74*1dedbd3bSFrançois Tigeot * Optional callback for the dirty fb IOCTL. 75*1dedbd3bSFrançois Tigeot * 76*1dedbd3bSFrançois Tigeot * Userspace can notify the driver via this callback that an area of the 77*1dedbd3bSFrançois Tigeot * framebuffer has changed and should be flushed to the display 78*1dedbd3bSFrançois Tigeot * hardware. This can also be used internally, e.g. by the fbdev 79*1dedbd3bSFrançois Tigeot * emulation, though that's not the case currently. 80*1dedbd3bSFrançois Tigeot * 81*1dedbd3bSFrançois Tigeot * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd 82*1dedbd3bSFrançois Tigeot * for more information as all the semantics and arguments have a one to 83*1dedbd3bSFrançois Tigeot * one mapping on this function. 84*1dedbd3bSFrançois Tigeot * 85*1dedbd3bSFrançois Tigeot * RETURNS: 86*1dedbd3bSFrançois Tigeot * 87*1dedbd3bSFrançois Tigeot * 0 on success or a negative error code on failure. 88*1dedbd3bSFrançois Tigeot */ 89*1dedbd3bSFrançois Tigeot int (*dirty)(struct drm_framebuffer *framebuffer, 90*1dedbd3bSFrançois Tigeot struct drm_file *file_priv, unsigned flags, 91*1dedbd3bSFrançois Tigeot unsigned color, struct drm_clip_rect *clips, 92*1dedbd3bSFrançois Tigeot unsigned num_clips); 93*1dedbd3bSFrançois Tigeot }; 94*1dedbd3bSFrançois Tigeot 95*1dedbd3bSFrançois Tigeot /** 96*1dedbd3bSFrançois Tigeot * struct drm_framebuffer - frame buffer object 97*1dedbd3bSFrançois Tigeot * 98*1dedbd3bSFrançois Tigeot * Note that the fb is refcounted for the benefit of driver internals, 99*1dedbd3bSFrançois Tigeot * for example some hw, disabling a CRTC/plane is asynchronous, and 100*1dedbd3bSFrançois Tigeot * scanout does not actually complete until the next vblank. So some 101*1dedbd3bSFrançois Tigeot * cleanup (like releasing the reference(s) on the backing GEM bo(s)) 102*1dedbd3bSFrançois Tigeot * should be deferred. In cases like this, the driver would like to 103*1dedbd3bSFrançois Tigeot * hold a ref to the fb even though it has already been removed from 104*1dedbd3bSFrançois Tigeot * userspace perspective. See drm_framebuffer_reference() and 105*1dedbd3bSFrançois Tigeot * drm_framebuffer_unreference(). 106*1dedbd3bSFrançois Tigeot * 107*1dedbd3bSFrançois Tigeot * The refcount is stored inside the mode object @base. 108*1dedbd3bSFrançois Tigeot */ 109*1dedbd3bSFrançois Tigeot struct drm_framebuffer { 110*1dedbd3bSFrançois Tigeot /** 111*1dedbd3bSFrançois Tigeot * @dev: DRM device this framebuffer belongs to 112*1dedbd3bSFrançois Tigeot */ 113*1dedbd3bSFrançois Tigeot struct drm_device *dev; 114*1dedbd3bSFrançois Tigeot /** 115*1dedbd3bSFrançois Tigeot * @head: Place on the dev->mode_config.fb_list, access protected by 116*1dedbd3bSFrançois Tigeot * dev->mode_config.fb_lock. 117*1dedbd3bSFrançois Tigeot */ 118*1dedbd3bSFrançois Tigeot struct list_head head; 119*1dedbd3bSFrançois Tigeot 120*1dedbd3bSFrançois Tigeot /** 121*1dedbd3bSFrançois Tigeot * @base: base modeset object structure, contains the reference count. 122*1dedbd3bSFrançois Tigeot */ 123*1dedbd3bSFrançois Tigeot struct drm_mode_object base; 124*1dedbd3bSFrançois Tigeot /** 125*1dedbd3bSFrançois Tigeot * @funcs: framebuffer vfunc table 126*1dedbd3bSFrançois Tigeot */ 127*1dedbd3bSFrançois Tigeot const struct drm_framebuffer_funcs *funcs; 128*1dedbd3bSFrançois Tigeot /** 129*1dedbd3bSFrançois Tigeot * @pitches: Line stride per buffer. For userspace created object this 130*1dedbd3bSFrançois Tigeot * is copied from drm_mode_fb_cmd2. 131*1dedbd3bSFrançois Tigeot */ 132*1dedbd3bSFrançois Tigeot unsigned int pitches[4]; 133*1dedbd3bSFrançois Tigeot /** 134*1dedbd3bSFrançois Tigeot * @offsets: Offset from buffer start to the actual pixel data in bytes, 135*1dedbd3bSFrançois Tigeot * per buffer. For userspace created object this is copied from 136*1dedbd3bSFrançois Tigeot * drm_mode_fb_cmd2. 137*1dedbd3bSFrançois Tigeot * 138*1dedbd3bSFrançois Tigeot * Note that this is a linear offset and does not take into account 139*1dedbd3bSFrançois Tigeot * tiling or buffer laytou per @modifier. It meant to be used when the 140*1dedbd3bSFrançois Tigeot * actual pixel data for this framebuffer plane starts at an offset, 141*1dedbd3bSFrançois Tigeot * e.g. when multiple planes are allocated within the same backing 142*1dedbd3bSFrançois Tigeot * storage buffer object. For tiled layouts this generally means it 143*1dedbd3bSFrançois Tigeot * @offsets must at least be tile-size aligned, but hardware often has 144*1dedbd3bSFrançois Tigeot * stricter requirements. 145*1dedbd3bSFrançois Tigeot * 146*1dedbd3bSFrançois Tigeot * This should not be used to specifiy x/y pixel offsets into the buffer 147*1dedbd3bSFrançois Tigeot * data (even for linear buffers). Specifying an x/y pixel offset is 148*1dedbd3bSFrançois Tigeot * instead done through the source rectangle in struct &drm_plane_state. 149*1dedbd3bSFrançois Tigeot */ 150*1dedbd3bSFrançois Tigeot unsigned int offsets[4]; 151*1dedbd3bSFrançois Tigeot /** 152*1dedbd3bSFrançois Tigeot * @modifier: Data layout modifier, per buffer. This is used to describe 153*1dedbd3bSFrançois Tigeot * tiling, or also special layouts (like compression) of auxiliary 154*1dedbd3bSFrançois Tigeot * buffers. For userspace created object this is copied from 155*1dedbd3bSFrançois Tigeot * drm_mode_fb_cmd2. 156*1dedbd3bSFrançois Tigeot */ 157*1dedbd3bSFrançois Tigeot uint64_t modifier[4]; 158*1dedbd3bSFrançois Tigeot /** 159*1dedbd3bSFrançois Tigeot * @width: Logical width of the visible area of the framebuffer, in 160*1dedbd3bSFrançois Tigeot * pixels. 161*1dedbd3bSFrançois Tigeot */ 162*1dedbd3bSFrançois Tigeot unsigned int width; 163*1dedbd3bSFrançois Tigeot /** 164*1dedbd3bSFrançois Tigeot * @height: Logical height of the visible area of the framebuffer, in 165*1dedbd3bSFrançois Tigeot * pixels. 166*1dedbd3bSFrançois Tigeot */ 167*1dedbd3bSFrançois Tigeot unsigned int height; 168*1dedbd3bSFrançois Tigeot /** 169*1dedbd3bSFrançois Tigeot * @depth: Depth in bits per pixel for RGB formats. 0 for everything 170*1dedbd3bSFrançois Tigeot * else. Legacy information derived from @pixel_format, it's suggested to use 171*1dedbd3bSFrançois Tigeot * the DRM FOURCC codes and helper functions directly instead. 172*1dedbd3bSFrançois Tigeot */ 173*1dedbd3bSFrançois Tigeot unsigned int depth; 174*1dedbd3bSFrançois Tigeot /** 175*1dedbd3bSFrançois Tigeot * @bits_per_pixel: Storage used bits per pixel for RGB formats. 0 for 176*1dedbd3bSFrançois Tigeot * everything else. Legacy information derived from @pixel_format, it's 177*1dedbd3bSFrançois Tigeot * suggested to use the DRM FOURCC codes and helper functions directly 178*1dedbd3bSFrançois Tigeot * instead. 179*1dedbd3bSFrançois Tigeot */ 180*1dedbd3bSFrançois Tigeot int bits_per_pixel; 181*1dedbd3bSFrançois Tigeot /** 182*1dedbd3bSFrançois Tigeot * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or 183*1dedbd3bSFrançois Tigeot * DRM_MODE_FB_MODIFIERS. 184*1dedbd3bSFrançois Tigeot */ 185*1dedbd3bSFrançois Tigeot int flags; 186*1dedbd3bSFrançois Tigeot /** 187*1dedbd3bSFrançois Tigeot * @pixel_format: DRM FOURCC code describing the pixel format. 188*1dedbd3bSFrançois Tigeot */ 189*1dedbd3bSFrançois Tigeot uint32_t pixel_format; /* fourcc format */ 190*1dedbd3bSFrançois Tigeot /** 191*1dedbd3bSFrançois Tigeot * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor 192*1dedbd3bSFrançois Tigeot * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 193*1dedbd3bSFrançois Tigeot * universal plane. 194*1dedbd3bSFrançois Tigeot */ 195*1dedbd3bSFrançois Tigeot int hot_x; 196*1dedbd3bSFrançois Tigeot /** 197*1dedbd3bSFrançois Tigeot * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor 198*1dedbd3bSFrançois Tigeot * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 199*1dedbd3bSFrançois Tigeot * universal plane. 200*1dedbd3bSFrançois Tigeot */ 201*1dedbd3bSFrançois Tigeot int hot_y; 202*1dedbd3bSFrançois Tigeot /** 203*1dedbd3bSFrançois Tigeot * @filp_head: Placed on struct &drm_file fbs list_head, protected by 204*1dedbd3bSFrançois Tigeot * fbs_lock in the same structure. 205*1dedbd3bSFrançois Tigeot */ 206*1dedbd3bSFrançois Tigeot struct list_head filp_head; 207*1dedbd3bSFrançois Tigeot }; 208*1dedbd3bSFrançois Tigeot 209*1dedbd3bSFrançois Tigeot #define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) 210*1dedbd3bSFrançois Tigeot 211*1dedbd3bSFrançois Tigeot int drm_framebuffer_init(struct drm_device *dev, 212*1dedbd3bSFrançois Tigeot struct drm_framebuffer *fb, 213*1dedbd3bSFrançois Tigeot const struct drm_framebuffer_funcs *funcs); 214*1dedbd3bSFrançois Tigeot struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 215*1dedbd3bSFrançois Tigeot uint32_t id); 216*1dedbd3bSFrançois Tigeot void drm_framebuffer_remove(struct drm_framebuffer *fb); 217*1dedbd3bSFrançois Tigeot void drm_framebuffer_cleanup(struct drm_framebuffer *fb); 218*1dedbd3bSFrançois Tigeot void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); 219*1dedbd3bSFrançois Tigeot 220*1dedbd3bSFrançois Tigeot /** 221*1dedbd3bSFrançois Tigeot * drm_framebuffer_reference - incr the fb refcnt 222*1dedbd3bSFrançois Tigeot * @fb: framebuffer 223*1dedbd3bSFrançois Tigeot * 224*1dedbd3bSFrançois Tigeot * This functions increments the fb's refcount. 225*1dedbd3bSFrançois Tigeot */ 226*1dedbd3bSFrançois Tigeot static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) 227*1dedbd3bSFrançois Tigeot { 228*1dedbd3bSFrançois Tigeot drm_mode_object_reference(&fb->base); 229*1dedbd3bSFrançois Tigeot } 230*1dedbd3bSFrançois Tigeot 231*1dedbd3bSFrançois Tigeot /** 232*1dedbd3bSFrançois Tigeot * drm_framebuffer_unreference - unref a framebuffer 233*1dedbd3bSFrançois Tigeot * @fb: framebuffer to unref 234*1dedbd3bSFrançois Tigeot * 235*1dedbd3bSFrançois Tigeot * This functions decrements the fb's refcount and frees it if it drops to zero. 236*1dedbd3bSFrançois Tigeot */ 237*1dedbd3bSFrançois Tigeot static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) 238*1dedbd3bSFrançois Tigeot { 239*1dedbd3bSFrançois Tigeot drm_mode_object_unreference(&fb->base); 240*1dedbd3bSFrançois Tigeot } 241*1dedbd3bSFrançois Tigeot 242*1dedbd3bSFrançois Tigeot /** 243*1dedbd3bSFrançois Tigeot * drm_framebuffer_read_refcount - read the framebuffer reference count. 244*1dedbd3bSFrançois Tigeot * @fb: framebuffer 245*1dedbd3bSFrançois Tigeot * 246*1dedbd3bSFrançois Tigeot * This functions returns the framebuffer's reference count. 247*1dedbd3bSFrançois Tigeot */ 248*1dedbd3bSFrançois Tigeot static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) 249*1dedbd3bSFrançois Tigeot { 250*1dedbd3bSFrançois Tigeot return atomic_read(&fb->base.refcount.refcount); 251*1dedbd3bSFrançois Tigeot } 252*1dedbd3bSFrançois Tigeot 253*1dedbd3bSFrançois Tigeot /** 254*1dedbd3bSFrançois Tigeot * drm_for_each_fb - iterate over all framebuffers 255*1dedbd3bSFrançois Tigeot * @fb: the loop cursor 256*1dedbd3bSFrançois Tigeot * @dev: the DRM device 257*1dedbd3bSFrançois Tigeot * 258*1dedbd3bSFrançois Tigeot * Iterate over all framebuffers of @dev. User must hold the fb_lock from 259*1dedbd3bSFrançois Tigeot * &drm_mode_config. 260*1dedbd3bSFrançois Tigeot */ 261*1dedbd3bSFrançois Tigeot #define drm_for_each_fb(fb, dev) \ 262*1dedbd3bSFrançois Tigeot for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ 263*1dedbd3bSFrançois Tigeot fb = list_first_entry(&(dev)->mode_config.fb_list, \ 264*1dedbd3bSFrançois Tigeot struct drm_framebuffer, head); \ 265*1dedbd3bSFrançois Tigeot &fb->head != (&(dev)->mode_config.fb_list); \ 266*1dedbd3bSFrançois Tigeot fb = list_next_entry(fb, head)) 267*1dedbd3bSFrançois Tigeot #endif 268