linux/include/drm/drm_fb_helper.h
<<
>>
Prefs
   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
  33struct drm_fb_helper;
  34
  35#include <linux/kgdb.h>
  36
  37enum mode_set_atomic {
  38        LEAVE_ATOMIC_MODE_SET,
  39        ENTER_ATOMIC_MODE_SET,
  40};
  41
  42struct drm_fb_offset {
  43        int x, y;
  44};
  45
  46struct drm_fb_helper_crtc {
  47        struct drm_mode_set mode_set;
  48        struct drm_display_mode *desired_mode;
  49        int x, y;
  50};
  51
  52/**
  53 * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
  54 * @fb_width: fbdev width
  55 * @fb_height: fbdev height
  56 * @surface_width: scanout buffer width
  57 * @surface_height: scanout buffer height
  58 * @surface_bpp: scanout buffer bpp
  59 * @surface_depth: scanout buffer depth
  60 *
  61 * Note that the scanout surface width/height may be larger than the fbdev
  62 * width/height.  In case of multiple displays, the scanout surface is sized
  63 * according to the largest width/height (so it is large enough for all CRTCs
  64 * to scanout).  But the fbdev width/height is sized to the minimum width/
  65 * height of all the displays.  This ensures that fbcon fits on the smallest
  66 * of the attached displays.
  67 *
  68 * So what is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
  69 * rather than the surface size.
  70 */
  71struct drm_fb_helper_surface_size {
  72        u32 fb_width;
  73        u32 fb_height;
  74        u32 surface_width;
  75        u32 surface_height;
  76        u32 surface_bpp;
  77        u32 surface_depth;
  78};
  79
  80/**
  81 * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library
  82 *
  83 * Driver callbacks used by the fbdev emulation helper library.
  84 */
  85struct drm_fb_helper_funcs {
  86        /**
  87         * @gamma_set:
  88         *
  89         * Set the given gamma LUT register on the given CRTC.
  90         *
  91         * This callback is optional.
  92         *
  93         * FIXME:
  94         *
  95         * This callback is functionally redundant with the core gamma table
  96         * support and simply exists because the fbdev hasn't yet been
  97         * refactored to use the core gamma table interfaces.
  98         */
  99        void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
 100                          u16 blue, int regno);
 101        /**
 102         * @gamma_get:
 103         *
 104         * Read the given gamma LUT register on the given CRTC, used to save the
 105         * current LUT when force-restoring the fbdev for e.g. kdbg.
 106         *
 107         * This callback is optional.
 108         *
 109         * FIXME:
 110         *
 111         * This callback is functionally redundant with the core gamma table
 112         * support and simply exists because the fbdev hasn't yet been
 113         * refactored to use the core gamma table interfaces.
 114         */
 115        void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
 116                          u16 *blue, int regno);
 117
 118        /**
 119         * @fb_probe:
 120         *
 121         * Driver callback to allocate and initialize the fbdev info structure.
 122         * Furthermore it also needs to allocate the DRM framebuffer used to
 123         * back the fbdev.
 124         *
 125         * This callback is mandatory.
 126         *
 127         * RETURNS:
 128         *
 129         * The driver should return 0 on success and a negative error code on
 130         * failure.
 131         */
 132        int (*fb_probe)(struct drm_fb_helper *helper,
 133                        struct drm_fb_helper_surface_size *sizes);
 134
 135        /**
 136         * @initial_config:
 137         *
 138         * Driver callback to setup an initial fbdev display configuration.
 139         * Drivers can use this callback to tell the fbdev emulation what the
 140         * preferred initial configuration is. This is useful to implement
 141         * smooth booting where the fbdev (and subsequently all userspace) never
 142         * changes the mode, but always inherits the existing configuration.
 143         *
 144         * This callback is optional.
 145         *
 146         * RETURNS:
 147         *
 148         * The driver should return true if a suitable initial configuration has
 149         * been filled out and false when the fbdev helper should fall back to
 150         * the default probing logic.
 151         */
 152        bool (*initial_config)(struct drm_fb_helper *fb_helper,
 153                               struct drm_fb_helper_crtc **crtcs,
 154                               struct drm_display_mode **modes,
 155                               struct drm_fb_offset *offsets,
 156                               bool *enabled, int width, int height);
 157};
 158
 159struct drm_fb_helper_connector {
 160        struct drm_connector *connector;
 161};
 162
 163/**
 164 * struct drm_fb_helper - main structure to emulate fbdev on top of KMS
 165 * @fb: Scanout framebuffer object
 166 * @dev: DRM device
 167 * @crtc_count: number of possible CRTCs
 168 * @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
 169 * @connector_count: number of connected connectors
 170 * @connector_info_alloc_count: size of connector_info
 171 * @connector_info: array of per-connector information
 172 * @funcs: driver callbacks for fb helper
 173 * @fbdev: emulated fbdev device info struct
 174 * @pseudo_palette: fake palette of 16 colors
 175 *
 176 * This is the main structure used by the fbdev helpers. Drivers supporting
 177 * fbdev emulation should embedded this into their overall driver structure.
 178 * Drivers must also fill out a struct &drm_fb_helper_funcs with a few
 179 * operations.
 180 */
 181struct drm_fb_helper {
 182        struct drm_framebuffer *fb;
 183        struct drm_device *dev;
 184        int crtc_count;
 185        struct drm_fb_helper_crtc *crtc_info;
 186        int connector_count;
 187        int connector_info_alloc_count;
 188        struct drm_fb_helper_connector **connector_info;
 189        const struct drm_fb_helper_funcs *funcs;
 190        struct fb_info *fbdev;
 191        u32 pseudo_palette[17];
 192
 193        /**
 194         * @kernel_fb_list:
 195         *
 196         * Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
 197         */
 198        struct list_head kernel_fb_list;
 199
 200        /**
 201         * @delayed_hotplug:
 202         *
 203         * A hotplug was received while fbdev wasn't in control of the DRM
 204         * device, i.e. another KMS master was active. The output configuration
 205         * needs to be reprobe when fbdev is in control again.
 206         */
 207        bool delayed_hotplug;
 208
 209        /**
 210         * @atomic:
 211         *
 212         * Use atomic updates for restore_fbdev_mode(), etc.  This defaults to
 213         * true if driver has DRIVER_ATOMIC feature flag, but drivers can
 214         * override it to true after drm_fb_helper_init() if they support atomic
 215         * modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper
 216         * does not require ASYNC commits).
 217         */
 218        bool atomic;
 219};
 220
 221#ifdef CONFIG_DRM_FBDEV_EMULATION
 222void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
 223                           const struct drm_fb_helper_funcs *funcs);
 224int drm_fb_helper_init(struct drm_device *dev,
 225                       struct drm_fb_helper *helper, int crtc_count,
 226                       int max_conn);
 227void drm_fb_helper_fini(struct drm_fb_helper *helper);
 228int drm_fb_helper_blank(int blank, struct fb_info *info);
 229int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
 230                              struct fb_info *info);
 231int drm_fb_helper_set_par(struct fb_info *info);
 232int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 233                            struct fb_info *info);
 234
 235int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
 236
 237struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
 238void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
 239void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper);
 240void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
 241                            uint32_t fb_width, uint32_t fb_height);
 242void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
 243                            uint32_t depth);
 244
 245void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
 246
 247ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
 248                               size_t count, loff_t *ppos);
 249ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
 250                                size_t count, loff_t *ppos);
 251
 252void drm_fb_helper_sys_fillrect(struct fb_info *info,
 253                                const struct fb_fillrect *rect);
 254void drm_fb_helper_sys_copyarea(struct fb_info *info,
 255                                const struct fb_copyarea *area);
 256void drm_fb_helper_sys_imageblit(struct fb_info *info,
 257                                 const struct fb_image *image);
 258
 259void drm_fb_helper_cfb_fillrect(struct fb_info *info,
 260                                const struct fb_fillrect *rect);
 261void drm_fb_helper_cfb_copyarea(struct fb_info *info,
 262                                const struct fb_copyarea *area);
 263void drm_fb_helper_cfb_imageblit(struct fb_info *info,
 264                                 const struct fb_image *image);
 265
 266void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state);
 267
 268int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
 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, int bpp_sel);
 272int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
 273int drm_fb_helper_debug_enter(struct fb_info *info);
 274int drm_fb_helper_debug_leave(struct fb_info *info);
 275struct drm_display_mode *
 276drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
 277                        int width, int height);
 278struct drm_display_mode *
 279drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
 280                      int width, int height);
 281
 282int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
 283int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 284                                       struct drm_connector *connector);
 285#else
 286static inline void drm_fb_helper_prepare(struct drm_device *dev,
 287                                        struct drm_fb_helper *helper,
 288                                        const struct drm_fb_helper_funcs *funcs)
 289{
 290}
 291
 292static inline int drm_fb_helper_init(struct drm_device *dev,
 293                       struct drm_fb_helper *helper, int crtc_count,
 294                       int max_conn)
 295{
 296        return 0;
 297}
 298
 299static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
 300{
 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 int
 326drm_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_fbi(struct drm_fb_helper *fb_helper)
 333{
 334        return NULL;
 335}
 336
 337static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
 338{
 339}
 340static inline void drm_fb_helper_release_fbi(struct drm_fb_helper *fb_helper)
 341{
 342}
 343
 344static inline void drm_fb_helper_fill_var(struct fb_info *info,
 345                                          struct drm_fb_helper *fb_helper,
 346                                          uint32_t fb_width, uint32_t fb_height)
 347{
 348}
 349
 350static inline void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
 351                                          uint32_t depth)
 352{
 353}
 354
 355static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
 356                                        struct fb_info *info)
 357{
 358        return 0;
 359}
 360
 361static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
 362{
 363}
 364
 365static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info,
 366                                             char __user *buf, size_t count,
 367                                             loff_t *ppos)
 368{
 369        return -ENODEV;
 370}
 371
 372static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info,
 373                                              const char __user *buf,
 374                                              size_t count, loff_t *ppos)
 375{
 376        return -ENODEV;
 377}
 378
 379static inline void drm_fb_helper_sys_fillrect(struct fb_info *info,
 380                                              const struct fb_fillrect *rect)
 381{
 382}
 383
 384static inline void drm_fb_helper_sys_copyarea(struct fb_info *info,
 385                                              const struct fb_copyarea *area)
 386{
 387}
 388
 389static inline void drm_fb_helper_sys_imageblit(struct fb_info *info,
 390                                               const struct fb_image *image)
 391{
 392}
 393
 394static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info,
 395                                              const struct fb_fillrect *rect)
 396{
 397}
 398
 399static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info,
 400                                              const struct fb_copyarea *area)
 401{
 402}
 403
 404static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
 405                                               const struct fb_image *image)
 406{
 407}
 408
 409static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
 410                                             int state)
 411{
 412}
 413
 414static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 415{
 416        return 0;
 417}
 418
 419static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
 420                                               int bpp_sel)
 421{
 422        return 0;
 423}
 424
 425static inline int
 426drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
 427{
 428        return 0;
 429}
 430
 431static inline int drm_fb_helper_debug_enter(struct fb_info *info)
 432{
 433        return 0;
 434}
 435
 436static inline int drm_fb_helper_debug_leave(struct fb_info *info)
 437{
 438        return 0;
 439}
 440
 441static inline struct drm_display_mode *
 442drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
 443                       int width, int height)
 444{
 445        return NULL;
 446}
 447
 448static inline struct drm_display_mode *
 449drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
 450                      int width, int height)
 451{
 452        return NULL;
 453}
 454
 455static inline int
 456drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
 457                                struct drm_connector *connector)
 458{
 459        return 0;
 460}
 461
 462static inline int
 463drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 464                                   struct drm_connector *connector)
 465{
 466        return 0;
 467}
 468#endif
 469#endif
 470