Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2006-2009 Red Hat Inc.
0003  * Copyright (c) 2006-2008 Intel Corporation
0004  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
0005  *
0006  * DRM framebuffer helper functions
0007  *
0008  * Permission to use, copy, modify, distribute, and sell this software and its
0009  * documentation for any purpose is hereby granted without fee, provided that
0010  * the above copyright notice appear in all copies and that both that copyright
0011  * notice and this permission notice appear in supporting documentation, and
0012  * that the name of the copyright holders not be used in advertising or
0013  * publicity pertaining to distribution of the software without specific,
0014  * written prior permission.  The copyright holders make no representations
0015  * about the suitability of this software for any purpose.  It is provided "as
0016  * is" without express or implied warranty.
0017  *
0018  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
0019  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
0020  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
0021  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
0022  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
0023  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
0024  * OF THIS SOFTWARE.
0025  *
0026  * Authors:
0027  *      Dave Airlie <airlied@linux.ie>
0028  *      Jesse Barnes <jesse.barnes@intel.com>
0029  */
0030 #ifndef DRM_FB_HELPER_H
0031 #define DRM_FB_HELPER_H
0032 
0033 struct drm_fb_helper;
0034 
0035 #include <drm/drm_client.h>
0036 #include <drm/drm_crtc.h>
0037 #include <drm/drm_device.h>
0038 #include <linux/fb.h>
0039 #include <linux/kgdb.h>
0040 
0041 enum mode_set_atomic {
0042     LEAVE_ATOMIC_MODE_SET,
0043     ENTER_ATOMIC_MODE_SET,
0044 };
0045 
0046 /**
0047  * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
0048  * @fb_width: fbdev width
0049  * @fb_height: fbdev height
0050  * @surface_width: scanout buffer width
0051  * @surface_height: scanout buffer height
0052  * @surface_bpp: scanout buffer bpp
0053  * @surface_depth: scanout buffer depth
0054  *
0055  * Note that the scanout surface width/height may be larger than the fbdev
0056  * width/height.  In case of multiple displays, the scanout surface is sized
0057  * according to the largest width/height (so it is large enough for all CRTCs
0058  * to scanout).  But the fbdev width/height is sized to the minimum width/
0059  * height of all the displays.  This ensures that fbcon fits on the smallest
0060  * of the attached displays. fb_width/fb_height is used by
0061  * drm_fb_helper_fill_info() to fill out the &fb_info.var structure.
0062  */
0063 struct drm_fb_helper_surface_size {
0064     u32 fb_width;
0065     u32 fb_height;
0066     u32 surface_width;
0067     u32 surface_height;
0068     u32 surface_bpp;
0069     u32 surface_depth;
0070 };
0071 
0072 /**
0073  * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
0074  *
0075  * Driver callbacks used by the fbdev emulation helper library.
0076  */
0077 struct drm_fb_helper_funcs {
0078     /**
0079      * @fb_probe:
0080      *
0081      * Driver callback to allocate and initialize the fbdev info structure.
0082      * Furthermore it also needs to allocate the DRM framebuffer used to
0083      * back the fbdev.
0084      *
0085      * This callback is mandatory.
0086      *
0087      * RETURNS:
0088      *
0089      * The driver should return 0 on success and a negative error code on
0090      * failure.
0091      */
0092     int (*fb_probe)(struct drm_fb_helper *helper,
0093             struct drm_fb_helper_surface_size *sizes);
0094 };
0095 
0096 /**
0097  * struct drm_fb_helper - main structure to emulate fbdev on top of KMS
0098  * @fb: Scanout framebuffer object
0099  * @dev: DRM device
0100  * @funcs: driver callbacks for fb helper
0101  * @fbdev: emulated fbdev device info struct
0102  * @pseudo_palette: fake palette of 16 colors
0103  * @damage_clip: clip rectangle used with deferred_io to accumulate damage to
0104  *                the screen buffer
0105  * @damage_lock: spinlock protecting @damage_clip
0106  * @damage_work: worker used to flush the framebuffer
0107  * @resume_work: worker used during resume if the console lock is already taken
0108  *
0109  * This is the main structure used by the fbdev helpers. Drivers supporting
0110  * fbdev emulation should embedded this into their overall driver structure.
0111  * Drivers must also fill out a &struct drm_fb_helper_funcs with a few
0112  * operations.
0113  */
0114 struct drm_fb_helper {
0115     /**
0116      * @client:
0117      *
0118      * DRM client used by the generic fbdev emulation.
0119      */
0120     struct drm_client_dev client;
0121 
0122     /**
0123      * @buffer:
0124      *
0125      * Framebuffer used by the generic fbdev emulation.
0126      */
0127     struct drm_client_buffer *buffer;
0128 
0129     struct drm_framebuffer *fb;
0130     struct drm_device *dev;
0131     const struct drm_fb_helper_funcs *funcs;
0132     struct fb_info *fbdev;
0133     u32 pseudo_palette[17];
0134     struct drm_clip_rect damage_clip;
0135     spinlock_t damage_lock;
0136     struct work_struct damage_work;
0137     struct work_struct resume_work;
0138 
0139     /**
0140      * @lock:
0141      *
0142      * Top-level FBDEV helper lock. This protects all internal data
0143      * structures and lists, such as @connector_info and @crtc_info.
0144      *
0145      * FIXME: fbdev emulation locking is a mess and long term we want to
0146      * protect all helper internal state with this lock as well as reduce
0147      * core KMS locking as much as possible.
0148      */
0149     struct mutex lock;
0150 
0151     /**
0152      * @kernel_fb_list:
0153      *
0154      * Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
0155      */
0156     struct list_head kernel_fb_list;
0157 
0158     /**
0159      * @delayed_hotplug:
0160      *
0161      * A hotplug was received while fbdev wasn't in control of the DRM
0162      * device, i.e. another KMS master was active. The output configuration
0163      * needs to be reprobe when fbdev is in control again.
0164      */
0165     bool delayed_hotplug;
0166 
0167     /**
0168      * @deferred_setup:
0169      *
0170      * If no outputs are connected (disconnected or unknown) the FB helper
0171      * code will defer setup until at least one of the outputs shows up.
0172      * This field keeps track of the status so that setup can be retried
0173      * at every hotplug event until it succeeds eventually.
0174      *
0175      * Protected by @lock.
0176      */
0177     bool deferred_setup;
0178 
0179     /**
0180      * @preferred_bpp:
0181      *
0182      * Temporary storage for the driver's preferred BPP setting passed to
0183      * FB helper initialization. This needs to be tracked so that deferred
0184      * FB helper setup can pass this on.
0185      *
0186      * See also: @deferred_setup
0187      */
0188     int preferred_bpp;
0189 };
0190 
0191 static inline struct drm_fb_helper *
0192 drm_fb_helper_from_client(struct drm_client_dev *client)
0193 {
0194     return container_of(client, struct drm_fb_helper, client);
0195 }
0196 
0197 /**
0198  * define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers
0199  *
0200  * Helper define to register default implementations of drm_fb_helper
0201  * functions. To be used in struct fb_ops of drm drivers.
0202  */
0203 #define DRM_FB_HELPER_DEFAULT_OPS \
0204     .fb_check_var   = drm_fb_helper_check_var, \
0205     .fb_set_par = drm_fb_helper_set_par, \
0206     .fb_setcmap = drm_fb_helper_setcmap, \
0207     .fb_blank   = drm_fb_helper_blank, \
0208     .fb_pan_display = drm_fb_helper_pan_display, \
0209     .fb_debug_enter = drm_fb_helper_debug_enter, \
0210     .fb_debug_leave = drm_fb_helper_debug_leave, \
0211     .fb_ioctl   = drm_fb_helper_ioctl
0212 
0213 #ifdef CONFIG_DRM_FBDEV_EMULATION
0214 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
0215                const struct drm_fb_helper_funcs *funcs);
0216 int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
0217 void drm_fb_helper_fini(struct drm_fb_helper *helper);
0218 int drm_fb_helper_blank(int blank, struct fb_info *info);
0219 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
0220                   struct fb_info *info);
0221 int drm_fb_helper_set_par(struct fb_info *info);
0222 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
0223                 struct fb_info *info);
0224 
0225 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
0226 
0227 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
0228 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
0229 void drm_fb_helper_fill_info(struct fb_info *info,
0230                  struct drm_fb_helper *fb_helper,
0231                  struct drm_fb_helper_surface_size *sizes);
0232 
0233 void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist);
0234 
0235 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
0236                    size_t count, loff_t *ppos);
0237 ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
0238                 size_t count, loff_t *ppos);
0239 
0240 void drm_fb_helper_sys_fillrect(struct fb_info *info,
0241                 const struct fb_fillrect *rect);
0242 void drm_fb_helper_sys_copyarea(struct fb_info *info,
0243                 const struct fb_copyarea *area);
0244 void drm_fb_helper_sys_imageblit(struct fb_info *info,
0245                  const struct fb_image *image);
0246 
0247 void drm_fb_helper_cfb_fillrect(struct fb_info *info,
0248                 const struct fb_fillrect *rect);
0249 void drm_fb_helper_cfb_copyarea(struct fb_info *info,
0250                 const struct fb_copyarea *area);
0251 void drm_fb_helper_cfb_imageblit(struct fb_info *info,
0252                  const struct fb_image *image);
0253 
0254 void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
0255 void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
0256                     bool suspend);
0257 
0258 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
0259 
0260 int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
0261             unsigned long arg);
0262 
0263 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
0264 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
0265 int drm_fb_helper_debug_enter(struct fb_info *info);
0266 int drm_fb_helper_debug_leave(struct fb_info *info);
0267 
0268 void drm_fb_helper_lastclose(struct drm_device *dev);
0269 void drm_fb_helper_output_poll_changed(struct drm_device *dev);
0270 
0271 void drm_fbdev_generic_setup(struct drm_device *dev,
0272                  unsigned int preferred_bpp);
0273 #else
0274 static inline void drm_fb_helper_prepare(struct drm_device *dev,
0275                     struct drm_fb_helper *helper,
0276                     const struct drm_fb_helper_funcs *funcs)
0277 {
0278 }
0279 
0280 static inline int drm_fb_helper_init(struct drm_device *dev,
0281                struct drm_fb_helper *helper)
0282 {
0283     /* So drivers can use it to free the struct */
0284     helper->dev = dev;
0285     dev->fb_helper = helper;
0286 
0287     return 0;
0288 }
0289 
0290 static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
0291 {
0292     if (helper && helper->dev)
0293         helper->dev->fb_helper = NULL;
0294 }
0295 
0296 static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
0297 {
0298     return 0;
0299 }
0300 
0301 static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
0302                         struct fb_info *info)
0303 {
0304     return 0;
0305 }
0306 
0307 static inline int drm_fb_helper_set_par(struct fb_info *info)
0308 {
0309     return 0;
0310 }
0311 
0312 static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
0313                       struct fb_info *info)
0314 {
0315     return 0;
0316 }
0317 
0318 static inline int
0319 drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
0320 {
0321     return 0;
0322 }
0323 
0324 static inline struct fb_info *
0325 drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper)
0326 {
0327     return NULL;
0328 }
0329 
0330 static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
0331 {
0332 }
0333 
0334 static inline void
0335 drm_fb_helper_fill_info(struct fb_info *info,
0336             struct drm_fb_helper *fb_helper,
0337             struct drm_fb_helper_surface_size *sizes)
0338 {
0339 }
0340 
0341 static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
0342                     struct fb_info *info)
0343 {
0344     return 0;
0345 }
0346 
0347 static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
0348                       unsigned long arg)
0349 {
0350     return 0;
0351 }
0352 
0353 static inline void drm_fb_helper_deferred_io(struct fb_info *info,
0354                          struct list_head *pagelist)
0355 {
0356 }
0357 
0358 static inline int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper)
0359 {
0360     return -ENODEV;
0361 }
0362 
0363 static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info,
0364                          char __user *buf, size_t count,
0365                          loff_t *ppos)
0366 {
0367     return -ENODEV;
0368 }
0369 
0370 static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info,
0371                           const char __user *buf,
0372                           size_t count, loff_t *ppos)
0373 {
0374     return -ENODEV;
0375 }
0376 
0377 static inline void drm_fb_helper_sys_fillrect(struct fb_info *info,
0378                           const struct fb_fillrect *rect)
0379 {
0380 }
0381 
0382 static inline void drm_fb_helper_sys_copyarea(struct fb_info *info,
0383                           const struct fb_copyarea *area)
0384 {
0385 }
0386 
0387 static inline void drm_fb_helper_sys_imageblit(struct fb_info *info,
0388                            const struct fb_image *image)
0389 {
0390 }
0391 
0392 static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info,
0393                           const struct fb_fillrect *rect)
0394 {
0395 }
0396 
0397 static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info,
0398                           const struct fb_copyarea *area)
0399 {
0400 }
0401 
0402 static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
0403                            const struct fb_image *image)
0404 {
0405 }
0406 
0407 static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
0408                          bool suspend)
0409 {
0410 }
0411 
0412 static inline void
0413 drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
0414 {
0415 }
0416 
0417 static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
0418 {
0419     return 0;
0420 }
0421 
0422 static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
0423                            int bpp_sel)
0424 {
0425     return 0;
0426 }
0427 
0428 static inline int drm_fb_helper_debug_enter(struct fb_info *info)
0429 {
0430     return 0;
0431 }
0432 
0433 static inline int drm_fb_helper_debug_leave(struct fb_info *info)
0434 {
0435     return 0;
0436 }
0437 
0438 static inline void drm_fb_helper_lastclose(struct drm_device *dev)
0439 {
0440 }
0441 
0442 static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
0443 {
0444 }
0445 
0446 static inline void
0447 drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
0448 {
0449 }
0450 
0451 #endif
0452 
0453 #endif