162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2016 Intel Corporation 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission to use, copy, modify, distribute, and sell this software and its 562306a36Sopenharmony_ci * documentation for any purpose is hereby granted without fee, provided that 662306a36Sopenharmony_ci * the above copyright notice appear in all copies and that both that copyright 762306a36Sopenharmony_ci * notice and this permission notice appear in supporting documentation, and 862306a36Sopenharmony_ci * that the name of the copyright holders not be used in advertising or 962306a36Sopenharmony_ci * publicity pertaining to distribution of the software without specific, 1062306a36Sopenharmony_ci * written prior permission. The copyright holders make no representations 1162306a36Sopenharmony_ci * about the suitability of this software for any purpose. It is provided "as 1262306a36Sopenharmony_ci * is" without express or implied warranty. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1562306a36Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1662306a36Sopenharmony_ci * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1762306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1862306a36Sopenharmony_ci * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1962306a36Sopenharmony_ci * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2062306a36Sopenharmony_ci * OF THIS SOFTWARE. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#ifndef __DRM_FRAMEBUFFER_H__ 2462306a36Sopenharmony_ci#define __DRM_FRAMEBUFFER_H__ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <linux/ctype.h> 2762306a36Sopenharmony_ci#include <linux/list.h> 2862306a36Sopenharmony_ci#include <linux/sched.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <drm/drm_fourcc.h> 3162306a36Sopenharmony_ci#include <drm/drm_mode_object.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistruct drm_clip_rect; 3462306a36Sopenharmony_cistruct drm_device; 3562306a36Sopenharmony_cistruct drm_file; 3662306a36Sopenharmony_cistruct drm_framebuffer; 3762306a36Sopenharmony_cistruct drm_gem_object; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/** 4062306a36Sopenharmony_ci * struct drm_framebuffer_funcs - framebuffer hooks 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_cistruct drm_framebuffer_funcs { 4362306a36Sopenharmony_ci /** 4462306a36Sopenharmony_ci * @destroy: 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Clean up framebuffer resources, specifically also unreference the 4762306a36Sopenharmony_ci * backing storage. The core guarantees to call this function for every 4862306a36Sopenharmony_ci * framebuffer successfully created by calling 4962306a36Sopenharmony_ci * &drm_mode_config_funcs.fb_create. Drivers must also call 5062306a36Sopenharmony_ci * drm_framebuffer_cleanup() to release DRM core resources for this 5162306a36Sopenharmony_ci * framebuffer. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_ci void (*destroy)(struct drm_framebuffer *framebuffer); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci /** 5662306a36Sopenharmony_ci * @create_handle: 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * Create a buffer handle in the driver-specific buffer manager (either 5962306a36Sopenharmony_ci * GEM or TTM) valid for the passed-in &struct drm_file. This is used by 6062306a36Sopenharmony_ci * the core to implement the GETFB IOCTL, which returns (for 6162306a36Sopenharmony_ci * sufficiently priviledged user) also a native buffer handle. This can 6262306a36Sopenharmony_ci * be used for seamless transitions between modesetting clients by 6362306a36Sopenharmony_ci * copying the current screen contents to a private buffer and blending 6462306a36Sopenharmony_ci * between that and the new contents. 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * GEM based drivers should call drm_gem_handle_create() to create the 6762306a36Sopenharmony_ci * handle. 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * RETURNS: 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci * 0 on success or a negative error code on failure. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci int (*create_handle)(struct drm_framebuffer *fb, 7462306a36Sopenharmony_ci struct drm_file *file_priv, 7562306a36Sopenharmony_ci unsigned int *handle); 7662306a36Sopenharmony_ci /** 7762306a36Sopenharmony_ci * @dirty: 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * Optional callback for the dirty fb IOCTL. 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci * Userspace can notify the driver via this callback that an area of the 8262306a36Sopenharmony_ci * framebuffer has changed and should be flushed to the display 8362306a36Sopenharmony_ci * hardware. This can also be used internally, e.g. by the fbdev 8462306a36Sopenharmony_ci * emulation, though that's not the case currently. 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd 8762306a36Sopenharmony_ci * for more information as all the semantics and arguments have a one to 8862306a36Sopenharmony_ci * one mapping on this function. 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * Atomic drivers should use drm_atomic_helper_dirtyfb() to implement 9162306a36Sopenharmony_ci * this hook. 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * RETURNS: 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci * 0 on success or a negative error code on failure. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_ci int (*dirty)(struct drm_framebuffer *framebuffer, 9862306a36Sopenharmony_ci struct drm_file *file_priv, unsigned flags, 9962306a36Sopenharmony_ci unsigned color, struct drm_clip_rect *clips, 10062306a36Sopenharmony_ci unsigned num_clips); 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/** 10462306a36Sopenharmony_ci * struct drm_framebuffer - frame buffer object 10562306a36Sopenharmony_ci * 10662306a36Sopenharmony_ci * Note that the fb is refcounted for the benefit of driver internals, 10762306a36Sopenharmony_ci * for example some hw, disabling a CRTC/plane is asynchronous, and 10862306a36Sopenharmony_ci * scanout does not actually complete until the next vblank. So some 10962306a36Sopenharmony_ci * cleanup (like releasing the reference(s) on the backing GEM bo(s)) 11062306a36Sopenharmony_ci * should be deferred. In cases like this, the driver would like to 11162306a36Sopenharmony_ci * hold a ref to the fb even though it has already been removed from 11262306a36Sopenharmony_ci * userspace perspective. See drm_framebuffer_get() and 11362306a36Sopenharmony_ci * drm_framebuffer_put(). 11462306a36Sopenharmony_ci * 11562306a36Sopenharmony_ci * The refcount is stored inside the mode object @base. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_cistruct drm_framebuffer { 11862306a36Sopenharmony_ci /** 11962306a36Sopenharmony_ci * @dev: DRM device this framebuffer belongs to 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ci struct drm_device *dev; 12262306a36Sopenharmony_ci /** 12362306a36Sopenharmony_ci * @head: Place on the &drm_mode_config.fb_list, access protected by 12462306a36Sopenharmony_ci * &drm_mode_config.fb_lock. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci struct list_head head; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /** 12962306a36Sopenharmony_ci * @base: base modeset object structure, contains the reference count. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci struct drm_mode_object base; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /** 13462306a36Sopenharmony_ci * @comm: Name of the process allocating the fb, used for fb dumping. 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ci char comm[TASK_COMM_LEN]; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /** 13962306a36Sopenharmony_ci * @format: framebuffer format information 14062306a36Sopenharmony_ci */ 14162306a36Sopenharmony_ci const struct drm_format_info *format; 14262306a36Sopenharmony_ci /** 14362306a36Sopenharmony_ci * @funcs: framebuffer vfunc table 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci const struct drm_framebuffer_funcs *funcs; 14662306a36Sopenharmony_ci /** 14762306a36Sopenharmony_ci * @pitches: Line stride per buffer. For userspace created object this 14862306a36Sopenharmony_ci * is copied from drm_mode_fb_cmd2. 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_ci unsigned int pitches[DRM_FORMAT_MAX_PLANES]; 15162306a36Sopenharmony_ci /** 15262306a36Sopenharmony_ci * @offsets: Offset from buffer start to the actual pixel data in bytes, 15362306a36Sopenharmony_ci * per buffer. For userspace created object this is copied from 15462306a36Sopenharmony_ci * drm_mode_fb_cmd2. 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * Note that this is a linear offset and does not take into account 15762306a36Sopenharmony_ci * tiling or buffer layout per @modifier. It is meant to be used when 15862306a36Sopenharmony_ci * the actual pixel data for this framebuffer plane starts at an offset, 15962306a36Sopenharmony_ci * e.g. when multiple planes are allocated within the same backing 16062306a36Sopenharmony_ci * storage buffer object. For tiled layouts this generally means its 16162306a36Sopenharmony_ci * @offsets must at least be tile-size aligned, but hardware often has 16262306a36Sopenharmony_ci * stricter requirements. 16362306a36Sopenharmony_ci * 16462306a36Sopenharmony_ci * This should not be used to specifiy x/y pixel offsets into the buffer 16562306a36Sopenharmony_ci * data (even for linear buffers). Specifying an x/y pixel offset is 16662306a36Sopenharmony_ci * instead done through the source rectangle in &struct drm_plane_state. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci unsigned int offsets[DRM_FORMAT_MAX_PLANES]; 16962306a36Sopenharmony_ci /** 17062306a36Sopenharmony_ci * @modifier: Data layout modifier. This is used to describe 17162306a36Sopenharmony_ci * tiling, or also special layouts (like compression) of auxiliary 17262306a36Sopenharmony_ci * buffers. For userspace created object this is copied from 17362306a36Sopenharmony_ci * drm_mode_fb_cmd2. 17462306a36Sopenharmony_ci */ 17562306a36Sopenharmony_ci uint64_t modifier; 17662306a36Sopenharmony_ci /** 17762306a36Sopenharmony_ci * @width: Logical width of the visible area of the framebuffer, in 17862306a36Sopenharmony_ci * pixels. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci unsigned int width; 18162306a36Sopenharmony_ci /** 18262306a36Sopenharmony_ci * @height: Logical height of the visible area of the framebuffer, in 18362306a36Sopenharmony_ci * pixels. 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_ci unsigned int height; 18662306a36Sopenharmony_ci /** 18762306a36Sopenharmony_ci * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or 18862306a36Sopenharmony_ci * DRM_MODE_FB_MODIFIERS. 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_ci int flags; 19162306a36Sopenharmony_ci /** 19262306a36Sopenharmony_ci * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor 19362306a36Sopenharmony_ci * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 19462306a36Sopenharmony_ci * universal plane. 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_ci int hot_x; 19762306a36Sopenharmony_ci /** 19862306a36Sopenharmony_ci * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor 19962306a36Sopenharmony_ci * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR 20062306a36Sopenharmony_ci * universal plane. 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_ci int hot_y; 20362306a36Sopenharmony_ci /** 20462306a36Sopenharmony_ci * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock. 20562306a36Sopenharmony_ci */ 20662306a36Sopenharmony_ci struct list_head filp_head; 20762306a36Sopenharmony_ci /** 20862306a36Sopenharmony_ci * @obj: GEM objects backing the framebuffer, one per plane (optional). 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * This is used by the GEM framebuffer helpers, see e.g. 21162306a36Sopenharmony_ci * drm_gem_fb_create(). 21262306a36Sopenharmony_ci */ 21362306a36Sopenharmony_ci struct drm_gem_object *obj[DRM_FORMAT_MAX_PLANES]; 21462306a36Sopenharmony_ci}; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciint drm_framebuffer_init(struct drm_device *dev, 21962306a36Sopenharmony_ci struct drm_framebuffer *fb, 22062306a36Sopenharmony_ci const struct drm_framebuffer_funcs *funcs); 22162306a36Sopenharmony_cistruct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, 22262306a36Sopenharmony_ci struct drm_file *file_priv, 22362306a36Sopenharmony_ci uint32_t id); 22462306a36Sopenharmony_civoid drm_framebuffer_remove(struct drm_framebuffer *fb); 22562306a36Sopenharmony_civoid drm_framebuffer_cleanup(struct drm_framebuffer *fb); 22662306a36Sopenharmony_civoid drm_framebuffer_unregister_private(struct drm_framebuffer *fb); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/** 22962306a36Sopenharmony_ci * drm_framebuffer_get - acquire a framebuffer reference 23062306a36Sopenharmony_ci * @fb: DRM framebuffer 23162306a36Sopenharmony_ci * 23262306a36Sopenharmony_ci * This function increments the framebuffer's reference count. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_cistatic inline void drm_framebuffer_get(struct drm_framebuffer *fb) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci drm_mode_object_get(&fb->base); 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/** 24062306a36Sopenharmony_ci * drm_framebuffer_put - release a framebuffer reference 24162306a36Sopenharmony_ci * @fb: DRM framebuffer 24262306a36Sopenharmony_ci * 24362306a36Sopenharmony_ci * This function decrements the framebuffer's reference count and frees the 24462306a36Sopenharmony_ci * framebuffer if the reference count drops to zero. 24562306a36Sopenharmony_ci */ 24662306a36Sopenharmony_cistatic inline void drm_framebuffer_put(struct drm_framebuffer *fb) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci drm_mode_object_put(&fb->base); 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/** 25262306a36Sopenharmony_ci * drm_framebuffer_read_refcount - read the framebuffer reference count. 25362306a36Sopenharmony_ci * @fb: framebuffer 25462306a36Sopenharmony_ci * 25562306a36Sopenharmony_ci * This functions returns the framebuffer's reference count. 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_cistatic inline uint32_t drm_framebuffer_read_refcount(const struct drm_framebuffer *fb) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci return kref_read(&fb->base.refcount); 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci/** 26362306a36Sopenharmony_ci * drm_framebuffer_assign - store a reference to the fb 26462306a36Sopenharmony_ci * @p: location to store framebuffer 26562306a36Sopenharmony_ci * @fb: new framebuffer (maybe NULL) 26662306a36Sopenharmony_ci * 26762306a36Sopenharmony_ci * This functions sets the location to store a reference to the framebuffer, 26862306a36Sopenharmony_ci * unreferencing the framebuffer that was previously stored in that location. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_cistatic inline void drm_framebuffer_assign(struct drm_framebuffer **p, 27162306a36Sopenharmony_ci struct drm_framebuffer *fb) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci if (fb) 27462306a36Sopenharmony_ci drm_framebuffer_get(fb); 27562306a36Sopenharmony_ci if (*p) 27662306a36Sopenharmony_ci drm_framebuffer_put(*p); 27762306a36Sopenharmony_ci *p = fb; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/* 28162306a36Sopenharmony_ci * drm_for_each_fb - iterate over all framebuffers 28262306a36Sopenharmony_ci * @fb: the loop cursor 28362306a36Sopenharmony_ci * @dev: the DRM device 28462306a36Sopenharmony_ci * 28562306a36Sopenharmony_ci * Iterate over all framebuffers of @dev. User must hold 28662306a36Sopenharmony_ci * &drm_mode_config.fb_lock. 28762306a36Sopenharmony_ci */ 28862306a36Sopenharmony_ci#define drm_for_each_fb(fb, dev) \ 28962306a36Sopenharmony_ci for (WARN_ON(!mutex_is_locked(&(dev)->mode_config.fb_lock)), \ 29062306a36Sopenharmony_ci fb = list_first_entry(&(dev)->mode_config.fb_list, \ 29162306a36Sopenharmony_ci struct drm_framebuffer, head); \ 29262306a36Sopenharmony_ci &fb->head != (&(dev)->mode_config.fb_list); \ 29362306a36Sopenharmony_ci fb = list_next_entry(fb, head)) 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciint drm_framebuffer_plane_width(int width, 29662306a36Sopenharmony_ci const struct drm_framebuffer *fb, int plane); 29762306a36Sopenharmony_ciint drm_framebuffer_plane_height(int height, 29862306a36Sopenharmony_ci const struct drm_framebuffer *fb, int plane); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/** 30162306a36Sopenharmony_ci * struct drm_afbc_framebuffer - a special afbc frame buffer object 30262306a36Sopenharmony_ci * 30362306a36Sopenharmony_ci * A derived class of struct drm_framebuffer, dedicated for afbc use cases. 30462306a36Sopenharmony_ci */ 30562306a36Sopenharmony_cistruct drm_afbc_framebuffer { 30662306a36Sopenharmony_ci /** 30762306a36Sopenharmony_ci * @base: base framebuffer structure. 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_ci struct drm_framebuffer base; 31062306a36Sopenharmony_ci /** 31162306a36Sopenharmony_ci * @block_width: width of a single afbc block 31262306a36Sopenharmony_ci */ 31362306a36Sopenharmony_ci u32 block_width; 31462306a36Sopenharmony_ci /** 31562306a36Sopenharmony_ci * @block_height: height of a single afbc block 31662306a36Sopenharmony_ci */ 31762306a36Sopenharmony_ci u32 block_height; 31862306a36Sopenharmony_ci /** 31962306a36Sopenharmony_ci * @aligned_width: aligned frame buffer width 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ci u32 aligned_width; 32262306a36Sopenharmony_ci /** 32362306a36Sopenharmony_ci * @aligned_height: aligned frame buffer height 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_ci u32 aligned_height; 32662306a36Sopenharmony_ci /** 32762306a36Sopenharmony_ci * @offset: offset of the first afbc header 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_ci u32 offset; 33062306a36Sopenharmony_ci /** 33162306a36Sopenharmony_ci * @afbc_size: minimum size of afbc buffer 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci u32 afbc_size; 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci#define fb_to_afbc_fb(x) container_of(x, struct drm_afbc_framebuffer, base) 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci#endif 339