root/include/drm/drm_fb_helper.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. drm_fb_helper_from_client
  2. drm_fb_helper_prepare
  3. drm_fb_helper_init
  4. drm_fb_helper_fini
  5. drm_fb_helper_blank
  6. drm_fb_helper_pan_display
  7. drm_fb_helper_set_par
  8. drm_fb_helper_check_var
  9. drm_fb_helper_restore_fbdev_mode_unlocked
  10. drm_fb_helper_alloc_fbi
  11. drm_fb_helper_unregister_fbi
  12. drm_fb_helper_fill_info
  13. drm_fb_helper_setcmap
  14. drm_fb_helper_ioctl
  15. drm_fb_helper_unlink_fbi
  16. drm_fb_helper_deferred_io
  17. drm_fb_helper_defio_init
  18. drm_fb_helper_sys_read
  19. drm_fb_helper_sys_write
  20. drm_fb_helper_sys_fillrect
  21. drm_fb_helper_sys_copyarea
  22. drm_fb_helper_sys_imageblit
  23. drm_fb_helper_cfb_fillrect
  24. drm_fb_helper_cfb_copyarea
  25. drm_fb_helper_cfb_imageblit
  26. drm_fb_helper_set_suspend
  27. drm_fb_helper_set_suspend_unlocked
  28. drm_fb_helper_hotplug_event
  29. drm_fb_helper_initial_config
  30. drm_fb_helper_debug_enter
  31. drm_fb_helper_debug_leave
  32. drm_fb_helper_fbdev_setup
  33. drm_fb_helper_fbdev_teardown
  34. drm_fb_helper_lastclose
  35. drm_fb_helper_output_poll_changed
  36. drm_fb_helper_generic_probe
  37. drm_fbdev_generic_setup
  38. drm_fb_helper_single_add_all_connectors
  39. drm_fb_helper_add_one_connector
  40. drm_fb_helper_remove_one_connector
  41. drm_fb_helper_remove_conflicting_framebuffers
  42. drm_fb_helper_remove_conflicting_pci_framebuffers

   1 /*
   2  * Copyright (c) 2006-2009 Red Hat Inc.
   3  * Copyright (c) 2006-2008 Intel Corporation
   4  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
   5  *
   6  * DRM framebuffer helper functions
   7  *
   8  * Permission to use, copy, modify, distribute, and sell this software and its
   9  * documentation for any purpose is hereby granted without fee, provided that
  10  * the above copyright notice appear in all copies and that both that copyright
  11  * notice and this permission notice appear in supporting documentation, and
  12  * that the name of the copyright holders not be used in advertising or
  13  * publicity pertaining to distribution of the software without specific,
  14  * written prior permission.  The copyright holders make no representations
  15  * about the suitability of this software for any purpose.  It is provided "as
  16  * 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 NO
  20  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  22  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  23  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  24  * 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_H
  31 #define DRM_FB_HELPER_H
  32 
  33 struct drm_fb_helper;
  34 
  35 #include <drm/drm_client.h>
  36 #include <drm/drm_crtc.h>
  37 #include <drm/drm_device.h>
  38 #include <linux/kgdb.h>
  39 #include <linux/vgaarb.h>
  40 
  41 enum mode_set_atomic {
  42         LEAVE_ATOMIC_MODE_SET,
  43         ENTER_ATOMIC_MODE_SET,
  44 };
  45 
  46 /**
  47  * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
  48  * @fb_width: fbdev width
  49  * @fb_height: fbdev height
  50  * @surface_width: scanout buffer width
  51  * @surface_height: scanout buffer height
  52  * @surface_bpp: scanout buffer bpp
  53  * @surface_depth: scanout buffer depth
  54  *
  55  * Note that the scanout surface width/height may be larger than the fbdev
  56  * width/height.  In case of multiple displays, the scanout surface is sized
  57  * according to the largest width/height (so it is large enough for all CRTCs
  58  * to scanout).  But the fbdev width/height is sized to the minimum width/
  59  * height of all the displays.  This ensures that fbcon fits on the smallest
  60  * of the attached displays. fb_width/fb_height is used by
  61  * drm_fb_helper_fill_info() to fill out the &fb_info.var structure.
  62  */
  63 struct drm_fb_helper_surface_size {
  64         u32 fb_width;
  65         u32 fb_height;
  66         u32 surface_width;
  67         u32 surface_height;
  68         u32 surface_bpp;
  69         u32 surface_depth;
  70 };
  71 
  72 /**
  73  * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
  74  *
  75  * Driver callbacks used by the fbdev emulation helper library.
  76  */
  77 struct drm_fb_helper_funcs {
  78         /**
  79          * @fb_probe:
  80          *
  81          * Driver callback to allocate and initialize the fbdev info structure.
  82          * Furthermore it also needs to allocate the DRM framebuffer used to
  83          * back the fbdev.
  84          *
  85          * This callback is mandatory.
  86          *
  87          * RETURNS:
  88          *
  89          * The driver should return 0 on success and a negative error code on
  90          * failure.
  91          */
  92         int (*fb_probe)(struct drm_fb_helper *helper,
  93                         struct drm_fb_helper_surface_size *sizes);
  94 };
  95 
  96 /**
  97  * struct drm_fb_helper - main structure to emulate fbdev on top of KMS
  98  * @fb: Scanout framebuffer object
  99  * @dev: DRM device
 100  * @funcs: driver callbacks for fb helper
 101  * @fbdev: emulated fbdev device info struct
 102  * @pseudo_palette: fake palette of 16 colors
 103  * @dirty_clip: clip rectangle used with deferred_io to accumulate damage to
 104  *              the screen buffer
 105  * @dirty_lock: spinlock protecting @dirty_clip
 106  * @dirty_work: worker used to flush the framebuffer
 107  * @resume_work: worker used during resume if the console lock is already taken
 108  *
 109  * This is the main structure used by the fbdev helpers. Drivers supporting
 110  * fbdev emulation should embedded this into their overall driver structure.
 111  * Drivers must also fill out a &struct drm_fb_helper_funcs with a few
 112  * operations.
 113  */
 114 struct drm_fb_helper {
 115         /**
 116          * @client:
 117          *
 118          * DRM client used by the generic fbdev emulation.
 119          */
 120         struct drm_client_dev client;
 121 
 122         /**
 123          * @buffer:
 124          *
 125          * Framebuffer used by the generic fbdev emulation.
 126          */
 127         struct drm_client_buffer *buffer;
 128 
 129         struct drm_framebuffer *fb;
 130         struct drm_device *dev;
 131         const struct drm_fb_helper_funcs *funcs;
 132         struct fb_info *fbdev;
 133         u32 pseudo_palette[17];
 134         struct drm_clip_rect dirty_clip;
 135         spinlock_t dirty_lock;
 136         struct work_struct dirty_work;
 137         struct work_struct resume_work;
 138 
 139         /**
 140          * @lock:
 141          *
 142          * Top-level FBDEV helper lock. This protects all internal data
 143          * structures and lists, such as @connector_info and @crtc_info.
 144          *
 145          * FIXME: fbdev emulation locking is a mess and long term we want to
 146          * protect all helper internal state with this lock as well as reduce
 147          * core KMS locking as much as possible.
 148          */
 149         struct mutex lock;
 150 
 151         /**
 152          * @kernel_fb_list:
 153          *
 154          * Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
 155          */
 156         struct list_head kernel_fb_list;
 157 
 158         /**
 159          * @delayed_hotplug:
 160          *
 161          * A hotplug was received while fbdev wasn't in control of the DRM
 162          * device, i.e. another KMS master was active. The output configuration
 163          * needs to be reprobe when fbdev is in control again.
 164          */
 165         bool delayed_hotplug;
 166 
 167         /**
 168          * @deferred_setup:
 169          *
 170          * If no outputs are connected (disconnected or unknown) the FB helper
 171          * code will defer setup until at least one of the outputs shows up.
 172          * This field keeps track of the status so that setup can be retried
 173          * at every hotplug event until it succeeds eventually.
 174          *
 175          * Protected by @lock.
 176          */
 177         bool deferred_setup;
 178 
 179         /**
 180          * @preferred_bpp:
 181          *
 182          * Temporary storage for the driver's preferred BPP setting passed to
 183          * FB helper initialization. This needs to be tracked so that deferred
 184          * FB helper setup can pass this on.
 185          *
 186          * See also: @deferred_setup
 187          */
 188         int preferred_bpp;
 189 };
 190 
 191 static inline struct drm_fb_helper *
 192 drm_fb_helper_from_client(struct drm_client_dev *client)
 193 {
 194         return container_of(client, struct drm_fb_helper, client);
 195 }
 196 
 197 /**
 198  * define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers
 199  *
 200  * Helper define to register default implementations of drm_fb_helper
 201  * functions. To be used in struct fb_ops of drm drivers.
 202  */
 203 #define DRM_FB_HELPER_DEFAULT_OPS \
 204         .fb_check_var   = drm_fb_helper_check_var, \
 205         .fb_set_par     = drm_fb_helper_set_par, \
 206         .fb_setcmap     = drm_fb_helper_setcmap, \
 207         .fb_blank       = drm_fb_helper_blank, \
 208         .fb_pan_display = drm_fb_helper_pan_display, \
 209         .fb_debug_enter = drm_fb_helper_debug_enter, \
 210         .fb_debug_leave = drm_fb_helper_debug_leave, \
 211         .fb_ioctl       = drm_fb_helper_ioctl
 212 
 213 #ifdef CONFIG_DRM_FBDEV_EMULATION
 214 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
 215                            const struct drm_fb_helper_funcs *funcs);
 216 int drm_fb_helper_init(struct drm_device *dev,
 217                        struct drm_fb_helper *helper, int max_conn);
 218 void drm_fb_helper_fini(struct drm_fb_helper *helper);
 219 int drm_fb_helper_blank(int blank, struct fb_info *info);
 220 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
 221                               struct fb_info *info);
 222 int drm_fb_helper_set_par(struct fb_info *info);
 223 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 224                             struct fb_info *info);
 225 
 226 int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
 227 
 228 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
 229 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
 230 void drm_fb_helper_fill_info(struct fb_info *info,
 231                              struct drm_fb_helper *fb_helper,
 232                              struct drm_fb_helper_surface_size *sizes);
 233 
 234 void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
 235 
 236 void drm_fb_helper_deferred_io(struct fb_info *info,
 237                                struct list_head *pagelist);
 238 int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper);
 239 
 240 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
 241                                size_t count, loff_t *ppos);
 242 ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
 243                                 size_t count, loff_t *ppos);
 244 
 245 void drm_fb_helper_sys_fillrect(struct fb_info *info,
 246                                 const struct fb_fillrect *rect);
 247 void drm_fb_helper_sys_copyarea(struct fb_info *info,
 248                                 const struct fb_copyarea *area);
 249 void drm_fb_helper_sys_imageblit(struct fb_info *info,
 250                                  const struct fb_image *image);
 251 
 252 void drm_fb_helper_cfb_fillrect(struct fb_info *info,
 253                                 const struct fb_fillrect *rect);
 254 void drm_fb_helper_cfb_copyarea(struct fb_info *info,
 255                                 const struct fb_copyarea *area);
 256 void drm_fb_helper_cfb_imageblit(struct fb_info *info,
 257                                  const struct fb_image *image);
 258 
 259 void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
 260 void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
 261                                         bool suspend);
 262 
 263 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
 264 
 265 int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
 266                         unsigned long arg);
 267 
 268 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
 269 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
 270 int drm_fb_helper_debug_enter(struct fb_info *info);
 271 int drm_fb_helper_debug_leave(struct fb_info *info);
 272 
 273 int drm_fb_helper_fbdev_setup(struct drm_device *dev,
 274                               struct drm_fb_helper *fb_helper,
 275                               const struct drm_fb_helper_funcs *funcs,
 276                               unsigned int preferred_bpp,
 277                               unsigned int max_conn_count);
 278 void drm_fb_helper_fbdev_teardown(struct drm_device *dev);
 279 
 280 void drm_fb_helper_lastclose(struct drm_device *dev);
 281 void drm_fb_helper_output_poll_changed(struct drm_device *dev);
 282 
 283 int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
 284                                 struct drm_fb_helper_surface_size *sizes);
 285 int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
 286 #else
 287 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 288                                         struct drm_fb_helper *helper,
 289                                         const struct drm_fb_helper_funcs *funcs)
 290 {
 291 }
 292 
 293 static inline int drm_fb_helper_init(struct drm_device *dev,
 294                        struct drm_fb_helper *helper,
 295                        int max_conn)
 296 {
 297         /* So drivers can use it to free the struct */
 298         helper->dev = dev;
 299         dev->fb_helper = helper;
 300 
 301         return 0;
 302 }
 303 
 304 static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
 305 {
 306         if (helper && helper->dev)
 307                 helper->dev->fb_helper = NULL;
 308 }
 309 
 310 static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
 311 {
 312         return 0;
 313 }
 314 
 315 static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
 316                                             struct fb_info *info)
 317 {
 318         return 0;
 319 }
 320 
 321 static inline int drm_fb_helper_set_par(struct fb_info *info)
 322 {
 323         return 0;
 324 }
 325 
 326 static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 327                                           struct fb_info *info)
 328 {
 329         return 0;
 330 }
 331 
 332 static inline int
 333 drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
 334 {
 335         return 0;
 336 }
 337 
 338 static inline struct fb_info *
 339 drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper)
 340 {
 341         return NULL;
 342 }
 343 
 344 static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
 345 {
 346 }
 347 
 348 static inline void
 349 drm_fb_helper_fill_info(struct fb_info *info,
 350                         struct drm_fb_helper *fb_helper,
 351                         struct drm_fb_helper_surface_size *sizes)
 352 {
 353 }
 354 
 355 static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
 356                                         struct fb_info *info)
 357 {
 358         return 0;
 359 }
 360 
 361 static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
 362                                       unsigned long arg)
 363 {
 364         return 0;
 365 }
 366 
 367 static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
 368 {
 369 }
 370 
 371 static inline void drm_fb_helper_deferred_io(struct fb_info *info,
 372                                              struct list_head *pagelist)
 373 {
 374 }
 375 
 376 static inline int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper)
 377 {
 378         return -ENODEV;
 379 }
 380 
 381 static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info,
 382                                              char __user *buf, size_t count,
 383                                              loff_t *ppos)
 384 {
 385         return -ENODEV;
 386 }
 387 
 388 static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info,
 389                                               const char __user *buf,
 390                                               size_t count, loff_t *ppos)
 391 {
 392         return -ENODEV;
 393 }
 394 
 395 static inline void drm_fb_helper_sys_fillrect(struct fb_info *info,
 396                                               const struct fb_fillrect *rect)
 397 {
 398 }
 399 
 400 static inline void drm_fb_helper_sys_copyarea(struct fb_info *info,
 401                                               const struct fb_copyarea *area)
 402 {
 403 }
 404 
 405 static inline void drm_fb_helper_sys_imageblit(struct fb_info *info,
 406                                                const struct fb_image *image)
 407 {
 408 }
 409 
 410 static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info,
 411                                               const struct fb_fillrect *rect)
 412 {
 413 }
 414 
 415 static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info,
 416                                               const struct fb_copyarea *area)
 417 {
 418 }
 419 
 420 static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
 421                                                const struct fb_image *image)
 422 {
 423 }
 424 
 425 static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
 426                                              bool suspend)
 427 {
 428 }
 429 
 430 static inline void
 431 drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
 432 {
 433 }
 434 
 435 static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 436 {
 437         return 0;
 438 }
 439 
 440 static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
 441                                                int bpp_sel)
 442 {
 443         return 0;
 444 }
 445 
 446 static inline int drm_fb_helper_debug_enter(struct fb_info *info)
 447 {
 448         return 0;
 449 }
 450 
 451 static inline int drm_fb_helper_debug_leave(struct fb_info *info)
 452 {
 453         return 0;
 454 }
 455 
 456 static inline int
 457 drm_fb_helper_fbdev_setup(struct drm_device *dev,
 458                           struct drm_fb_helper *fb_helper,
 459                           const struct drm_fb_helper_funcs *funcs,
 460                           unsigned int preferred_bpp,
 461                           unsigned int max_conn_count)
 462 {
 463         /* So drivers can use it to free the struct */
 464         dev->fb_helper = fb_helper;
 465 
 466         return 0;
 467 }
 468 
 469 static inline void drm_fb_helper_fbdev_teardown(struct drm_device *dev)
 470 {
 471         dev->fb_helper = NULL;
 472 }
 473 
 474 static inline void drm_fb_helper_lastclose(struct drm_device *dev)
 475 {
 476 }
 477 
 478 static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
 479 {
 480 }
 481 
 482 static inline int
 483 drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
 484                             struct drm_fb_helper_surface_size *sizes)
 485 {
 486         return 0;
 487 }
 488 
 489 static inline int
 490 drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
 491 {
 492         return 0;
 493 }
 494 
 495 #endif
 496 
 497 /* TODO: There's a todo entry to remove these three */
 498 static inline int
 499 drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 500 {
 501         return 0;
 502 }
 503 
 504 static inline int
 505 drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
 506                                 struct drm_connector *connector)
 507 {
 508         return 0;
 509 }
 510 
 511 static inline int
 512 drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 513                                    struct drm_connector *connector)
 514 {
 515         return 0;
 516 }
 517 
 518 /**
 519  * drm_fb_helper_remove_conflicting_framebuffers - remove firmware-configured framebuffers
 520  * @a: memory range, users of which are to be removed
 521  * @name: requesting driver name
 522  * @primary: also kick vga16fb if present
 523  *
 524  * This function removes framebuffer devices (initialized by firmware/bootloader)
 525  * which use memory range described by @a. If @a is NULL all such devices are
 526  * removed.
 527  */
 528 static inline int
 529 drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
 530                                               const char *name, bool primary)
 531 {
 532 #if IS_REACHABLE(CONFIG_FB)
 533         return remove_conflicting_framebuffers(a, name, primary);
 534 #else
 535         return 0;
 536 #endif
 537 }
 538 
 539 /**
 540  * drm_fb_helper_remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
 541  * @pdev: PCI device
 542  * @resource_id: index of PCI BAR configuring framebuffer memory
 543  * @name: requesting driver name
 544  *
 545  * This function removes framebuffer devices (eg. initialized by firmware)
 546  * using memory range configured for @pdev's BAR @resource_id.
 547  *
 548  * The function assumes that PCI device with shadowed ROM drives a primary
 549  * display and so kicks out vga16fb.
 550  */
 551 static inline int
 552 drm_fb_helper_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
 553                                                   int resource_id,
 554                                                   const char *name)
 555 {
 556         int ret = 0;
 557 
 558         /*
 559          * WARNING: Apparently we must kick fbdev drivers before vgacon,
 560          * otherwise the vga fbdev driver falls over.
 561          */
 562 #if IS_REACHABLE(CONFIG_FB)
 563         ret = remove_conflicting_pci_framebuffers(pdev, resource_id, name);
 564 #endif
 565         if (ret == 0)
 566                 ret = vga_remove_vgacon(pdev);
 567         return ret;
 568 }
 569 
 570 #endif

/* [<][>][^][v][top][bottom][index][help] */