brintos

brintos / linux-shallow public Read only

0
0
Text · 11.6 KiB · 699f279 Raw
405 lines · c
1/*2 * Copyright (c) 2006-2009 Red Hat Inc.3 * Copyright (c) 2006-2008 Intel Corporation4 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>5 *6 * DRM framebuffer helper functions7 *8 * Permission to use, copy, modify, distribute, and sell this software and its9 * documentation for any purpose is hereby granted without fee, provided that10 * the above copyright notice appear in all copies and that both that copyright11 * notice and this permission notice appear in supporting documentation, and12 * that the name of the copyright holders not be used in advertising or13 * publicity pertaining to distribution of the software without specific,14 * written prior permission.  The copyright holders make no representations15 * about the suitability of this software for any purpose.  It is provided "as16 * is" without express or implied warranty.17 *18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE24 * OF THIS SOFTWARE.25 *26 * Authors:27 *      Dave Airlie <airlied@linux.ie>28 *      Jesse Barnes <jesse.barnes@intel.com>29 */30#ifndef DRM_FB_HELPER_H31#define DRM_FB_HELPER_H32 33struct drm_clip_rect;34struct drm_fb_helper;35 36#include <linux/fb.h>37 38#include <drm/drm_client.h>39 40/**41 * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size42 * @fb_width: fbdev width43 * @fb_height: fbdev height44 * @surface_width: scanout buffer width45 * @surface_height: scanout buffer height46 * @surface_bpp: scanout buffer bpp47 * @surface_depth: scanout buffer depth48 *49 * Note that the scanout surface width/height may be larger than the fbdev50 * width/height.  In case of multiple displays, the scanout surface is sized51 * according to the largest width/height (so it is large enough for all CRTCs52 * to scanout).  But the fbdev width/height is sized to the minimum width/53 * height of all the displays.  This ensures that fbcon fits on the smallest54 * of the attached displays. fb_width/fb_height is used by55 * drm_fb_helper_fill_info() to fill out the &fb_info.var structure.56 */57struct drm_fb_helper_surface_size {58	u32 fb_width;59	u32 fb_height;60	u32 surface_width;61	u32 surface_height;62	u32 surface_bpp;63	u32 surface_depth;64};65 66/**67 * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library68 *69 * Driver callbacks used by the fbdev emulation helper library.70 */71struct drm_fb_helper_funcs {72	/**73	 * @fb_probe:74	 *75	 * Driver callback to allocate and initialize the fbdev info structure.76	 * Furthermore it also needs to allocate the DRM framebuffer used to77	 * back the fbdev.78	 *79	 * This callback is mandatory.80	 *81	 * RETURNS:82	 *83	 * The driver should return 0 on success and a negative error code on84	 * failure.85	 */86	int (*fb_probe)(struct drm_fb_helper *helper,87			struct drm_fb_helper_surface_size *sizes);88 89	/**90	 * @fb_dirty:91	 *92	 * Driver callback to update the framebuffer memory. If set, fbdev93	 * emulation will invoke this callback in regular intervals after94	 * the framebuffer has been written.95	 *96	 * This callback is optional.97	 *98	 * Returns:99	 * 0 on success, or an error code otherwise.100	 */101	int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip);102};103 104/**105 * struct drm_fb_helper - main structure to emulate fbdev on top of KMS106 * @fb: Scanout framebuffer object107 * @dev: DRM device108 * @funcs: driver callbacks for fb helper109 * @info: emulated fbdev device info struct110 * @pseudo_palette: fake palette of 16 colors111 * @damage_clip: clip rectangle used with deferred_io to accumulate damage to112 *                the screen buffer113 * @damage_lock: spinlock protecting @damage_clip114 * @damage_work: worker used to flush the framebuffer115 * @resume_work: worker used during resume if the console lock is already taken116 *117 * This is the main structure used by the fbdev helpers. Drivers supporting118 * fbdev emulation should embedded this into their overall driver structure.119 * Drivers must also fill out a &struct drm_fb_helper_funcs with a few120 * operations.121 */122struct drm_fb_helper {123	/**124	 * @client:125	 *126	 * DRM client used by the generic fbdev emulation.127	 */128	struct drm_client_dev client;129 130	/**131	 * @buffer:132	 *133	 * Framebuffer used by the generic fbdev emulation.134	 */135	struct drm_client_buffer *buffer;136 137	struct drm_framebuffer *fb;138	struct drm_device *dev;139	const struct drm_fb_helper_funcs *funcs;140	struct fb_info *info;141	u32 pseudo_palette[17];142	struct drm_clip_rect damage_clip;143	spinlock_t damage_lock;144	struct work_struct damage_work;145	struct work_struct resume_work;146 147	/**148	 * @lock:149	 *150	 * Top-level FBDEV helper lock. This protects all internal data151	 * structures and lists, such as @connector_info and @crtc_info.152	 *153	 * FIXME: fbdev emulation locking is a mess and long term we want to154	 * protect all helper internal state with this lock as well as reduce155	 * core KMS locking as much as possible.156	 */157	struct mutex lock;158 159	/**160	 * @kernel_fb_list:161	 *162	 * Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.163	 */164	struct list_head kernel_fb_list;165 166	/**167	 * @delayed_hotplug:168	 *169	 * A hotplug was received while fbdev wasn't in control of the DRM170	 * device, i.e. another KMS master was active. The output configuration171	 * needs to be reprobe when fbdev is in control again.172	 */173	bool delayed_hotplug;174 175	/**176	 * @deferred_setup:177	 *178	 * If no outputs are connected (disconnected or unknown) the FB helper179	 * code will defer setup until at least one of the outputs shows up.180	 * This field keeps track of the status so that setup can be retried181	 * at every hotplug event until it succeeds eventually.182	 *183	 * Protected by @lock.184	 */185	bool deferred_setup;186 187	/**188	 * @preferred_bpp:189	 *190	 * Temporary storage for the driver's preferred BPP setting passed to191	 * FB helper initialization. This needs to be tracked so that deferred192	 * FB helper setup can pass this on.193	 *194	 * See also: @deferred_setup195	 */196	int preferred_bpp;197 198#ifdef CONFIG_FB_DEFERRED_IO199	/**200	 * @fbdefio:201	 *202	 * Temporary storage for the driver's FB deferred I/O handler. If the203	 * driver uses the DRM fbdev emulation layer, this is set by the core204	 * to a generic deferred I/O handler if a driver is preferring to use205	 * a shadow buffer.206	 */207	struct fb_deferred_io fbdefio;208#endif209};210 211static inline struct drm_fb_helper *212drm_fb_helper_from_client(struct drm_client_dev *client)213{214	return container_of(client, struct drm_fb_helper, client);215}216 217/**218 * define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers219 *220 * Helper define to register default implementations of drm_fb_helper221 * functions. To be used in struct fb_ops of drm drivers.222 */223#define DRM_FB_HELPER_DEFAULT_OPS \224	.fb_check_var	= drm_fb_helper_check_var, \225	.fb_set_par	= drm_fb_helper_set_par, \226	.fb_setcmap	= drm_fb_helper_setcmap, \227	.fb_blank	= drm_fb_helper_blank, \228	.fb_pan_display	= drm_fb_helper_pan_display, \229	.fb_debug_enter = drm_fb_helper_debug_enter, \230	.fb_debug_leave = drm_fb_helper_debug_leave, \231	.fb_ioctl	= drm_fb_helper_ioctl232 233#ifdef CONFIG_DRM_FBDEV_EMULATION234void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,235			   unsigned int preferred_bpp,236			   const struct drm_fb_helper_funcs *funcs);237void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);238int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);239void drm_fb_helper_fini(struct drm_fb_helper *helper);240int drm_fb_helper_blank(int blank, struct fb_info *info);241int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,242			      struct fb_info *info);243int drm_fb_helper_set_par(struct fb_info *info);244int drm_fb_helper_check_var(struct fb_var_screeninfo *var,245			    struct fb_info *info);246 247int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);248 249struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper);250void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper);251void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);252void drm_fb_helper_fill_info(struct fb_info *info,253			     struct drm_fb_helper *fb_helper,254			     struct drm_fb_helper_surface_size *sizes);255 256void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);257void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height);258 259void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist);260 261void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);262void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,263					bool suspend);264 265int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);266 267int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,268			unsigned long arg);269 270int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);271int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);272int drm_fb_helper_debug_enter(struct fb_info *info);273int drm_fb_helper_debug_leave(struct fb_info *info);274void drm_fb_helper_lastclose(struct drm_device *dev);275#else276static inline void drm_fb_helper_prepare(struct drm_device *dev,277					 struct drm_fb_helper *helper,278					 unsigned int preferred_bpp,279					 const struct drm_fb_helper_funcs *funcs)280{281}282 283static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)284{285}286 287static inline int drm_fb_helper_init(struct drm_device *dev,288		       struct drm_fb_helper *helper)289{290	/* So drivers can use it to free the struct */291	helper->dev = dev;292	dev->fb_helper = helper;293 294	return 0;295}296 297static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)298{299	if (helper && helper->dev)300		helper->dev->fb_helper = NULL;301}302 303static inline int drm_fb_helper_blank(int blank, struct fb_info *info)304{305	return 0;306}307 308static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,309					    struct fb_info *info)310{311	return 0;312}313 314static inline int drm_fb_helper_set_par(struct fb_info *info)315{316	return 0;317}318 319static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,320					  struct fb_info *info)321{322	return 0;323}324 325static inline int326drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)327{328	return 0;329}330 331static inline struct fb_info *332drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)333{334	return NULL;335}336 337static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)338{339}340 341static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)342{343}344 345static inline void346drm_fb_helper_fill_info(struct fb_info *info,347			struct drm_fb_helper *fb_helper,348			struct drm_fb_helper_surface_size *sizes)349{350}351 352static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,353					struct fb_info *info)354{355	return 0;356}357 358static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,359				      unsigned long arg)360{361	return 0;362}363 364static inline void drm_fb_helper_deferred_io(struct fb_info *info,365					     struct list_head *pagelist)366{367}368 369static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,370					     bool suspend)371{372}373 374static inline void375drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)376{377}378 379static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)380{381	return 0;382}383 384static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)385{386	return 0;387}388 389static inline int drm_fb_helper_debug_enter(struct fb_info *info)390{391	return 0;392}393 394static inline int drm_fb_helper_debug_leave(struct fb_info *info)395{396	return 0;397}398 399static inline void drm_fb_helper_lastclose(struct drm_device *dev)400{401}402#endif403 404#endif405