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