linux/drivers/gpu/drm/i915/intel_fbdev.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2007 David Airlie
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 *     David Airlie
  25 */
  26
  27#include <linux/module.h>
  28#include <linux/kernel.h>
  29#include <linux/errno.h>
  30#include <linux/string.h>
  31#include <linux/mm.h>
  32#include <linux/tty.h>
  33#include <linux/sysrq.h>
  34#include <linux/delay.h>
  35#include <linux/fb.h>
  36#include <linux/init.h>
  37#include <linux/vga_switcheroo.h>
  38
  39#include <drm/drmP.h>
  40#include <drm/drm_crtc.h>
  41#include <drm/drm_fb_helper.h>
  42#include "intel_drv.h"
  43#include <drm/i915_drm.h>
  44#include "i915_drv.h"
  45
  46static struct fb_ops intelfb_ops = {
  47        .owner = THIS_MODULE,
  48        .fb_check_var = drm_fb_helper_check_var,
  49        .fb_set_par = drm_fb_helper_set_par,
  50        .fb_fillrect = cfb_fillrect,
  51        .fb_copyarea = cfb_copyarea,
  52        .fb_imageblit = cfb_imageblit,
  53        .fb_pan_display = drm_fb_helper_pan_display,
  54        .fb_blank = drm_fb_helper_blank,
  55        .fb_setcmap = drm_fb_helper_setcmap,
  56        .fb_debug_enter = drm_fb_helper_debug_enter,
  57        .fb_debug_leave = drm_fb_helper_debug_leave,
  58};
  59
  60static int intelfb_alloc(struct drm_fb_helper *helper,
  61                         struct drm_fb_helper_surface_size *sizes)
  62{
  63        struct intel_fbdev *ifbdev =
  64                container_of(helper, struct intel_fbdev, helper);
  65        struct drm_framebuffer *fb;
  66        struct drm_device *dev = helper->dev;
  67        struct drm_mode_fb_cmd2 mode_cmd = {};
  68        struct drm_i915_gem_object *obj;
  69        int size, ret;
  70
  71        /* we don't do packed 24bpp */
  72        if (sizes->surface_bpp == 24)
  73                sizes->surface_bpp = 32;
  74
  75        mode_cmd.width = sizes->surface_width;
  76        mode_cmd.height = sizes->surface_height;
  77
  78        mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
  79                                    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
  80        mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
  81                                                          sizes->surface_depth);
  82
  83        size = mode_cmd.pitches[0] * mode_cmd.height;
  84        size = ALIGN(size, PAGE_SIZE);
  85        obj = i915_gem_object_create_stolen(dev, size);
  86        if (obj == NULL)
  87                obj = i915_gem_alloc_object(dev, size);
  88        if (!obj) {
  89                DRM_ERROR("failed to allocate framebuffer\n");
  90                ret = -ENOMEM;
  91                goto out;
  92        }
  93
  94        /* Flush everything out, we'll be doing GTT only from now on */
  95        ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
  96        if (ret) {
  97                DRM_ERROR("failed to pin obj: %d\n", ret);
  98                goto out_unref;
  99        }
 100
 101        fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
 102        if (IS_ERR(fb)) {
 103                ret = PTR_ERR(fb);
 104                goto out_unpin;
 105        }
 106
 107        ifbdev->fb = to_intel_framebuffer(fb);
 108
 109        return 0;
 110
 111out_unpin:
 112        i915_gem_object_ggtt_unpin(obj);
 113out_unref:
 114        drm_gem_object_unreference(&obj->base);
 115out:
 116        return ret;
 117}
 118
 119static int intelfb_create(struct drm_fb_helper *helper,
 120                          struct drm_fb_helper_surface_size *sizes)
 121{
 122        struct intel_fbdev *ifbdev =
 123                container_of(helper, struct intel_fbdev, helper);
 124        struct intel_framebuffer *intel_fb = ifbdev->fb;
 125        struct drm_device *dev = helper->dev;
 126        struct drm_i915_private *dev_priv = dev->dev_private;
 127        struct fb_info *info;
 128        struct drm_framebuffer *fb;
 129        struct drm_i915_gem_object *obj;
 130        int size, ret;
 131        bool prealloc = false;
 132
 133        mutex_lock(&dev->struct_mutex);
 134
 135        if (intel_fb &&
 136            (sizes->fb_width > intel_fb->base.width ||
 137             sizes->fb_height > intel_fb->base.height)) {
 138                DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
 139                              " releasing it\n",
 140                              intel_fb->base.width, intel_fb->base.height,
 141                              sizes->fb_width, sizes->fb_height);
 142                drm_framebuffer_unreference(&intel_fb->base);
 143                intel_fb = ifbdev->fb = NULL;
 144        }
 145        if (!intel_fb || WARN_ON(!intel_fb->obj)) {
 146                DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
 147                ret = intelfb_alloc(helper, sizes);
 148                if (ret)
 149                        goto out_unlock;
 150                intel_fb = ifbdev->fb;
 151        } else {
 152                DRM_DEBUG_KMS("re-using BIOS fb\n");
 153                prealloc = true;
 154                sizes->fb_width = intel_fb->base.width;
 155                sizes->fb_height = intel_fb->base.height;
 156        }
 157
 158        obj = intel_fb->obj;
 159        size = obj->base.size;
 160
 161        info = framebuffer_alloc(0, &dev->pdev->dev);
 162        if (!info) {
 163                ret = -ENOMEM;
 164                goto out_unpin;
 165        }
 166
 167        info->par = helper;
 168
 169        fb = &ifbdev->fb->base;
 170
 171        ifbdev->helper.fb = fb;
 172        ifbdev->helper.fbdev = info;
 173
 174        strcpy(info->fix.id, "inteldrmfb");
 175
 176        info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
 177        info->fbops = &intelfb_ops;
 178
 179        ret = fb_alloc_cmap(&info->cmap, 256, 0);
 180        if (ret) {
 181                ret = -ENOMEM;
 182                goto out_unpin;
 183        }
 184        /* setup aperture base/size for vesafb takeover */
 185        info->apertures = alloc_apertures(1);
 186        if (!info->apertures) {
 187                ret = -ENOMEM;
 188                goto out_unpin;
 189        }
 190        info->apertures->ranges[0].base = dev->mode_config.fb_base;
 191        info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
 192
 193        info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
 194        info->fix.smem_len = size;
 195
 196        info->screen_base =
 197                ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
 198                           size);
 199        if (!info->screen_base) {
 200                ret = -ENOSPC;
 201                goto out_unpin;
 202        }
 203        info->screen_size = size;
 204
 205        /* This driver doesn't need a VT switch to restore the mode on resume */
 206        info->skip_vt_switch = true;
 207
 208        drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
 209        drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
 210
 211        /* If the object is shmemfs backed, it will have given us zeroed pages.
 212         * If the object is stolen however, it will be full of whatever
 213         * garbage was left in there.
 214         */
 215        if (ifbdev->fb->obj->stolen && !prealloc)
 216                memset_io(info->screen_base, 0, info->screen_size);
 217
 218        /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 219
 220        DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
 221                      fb->width, fb->height,
 222                      i915_gem_obj_ggtt_offset(obj), obj);
 223
 224        mutex_unlock(&dev->struct_mutex);
 225        vga_switcheroo_client_fb_set(dev->pdev, info);
 226        return 0;
 227
 228out_unpin:
 229        i915_gem_object_ggtt_unpin(obj);
 230        drm_gem_object_unreference(&obj->base);
 231out_unlock:
 232        mutex_unlock(&dev->struct_mutex);
 233        return ret;
 234}
 235
 236/** Sets the color ramps on behalf of RandR */
 237static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 238                                    u16 blue, int regno)
 239{
 240        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 241
 242        intel_crtc->lut_r[regno] = red >> 8;
 243        intel_crtc->lut_g[regno] = green >> 8;
 244        intel_crtc->lut_b[regno] = blue >> 8;
 245}
 246
 247static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 248                                    u16 *blue, int regno)
 249{
 250        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 251
 252        *red = intel_crtc->lut_r[regno] << 8;
 253        *green = intel_crtc->lut_g[regno] << 8;
 254        *blue = intel_crtc->lut_b[regno] << 8;
 255}
 256
 257static struct drm_fb_helper_crtc *
 258intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
 259{
 260        int i;
 261
 262        for (i = 0; i < fb_helper->crtc_count; i++)
 263                if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
 264                        return &fb_helper->crtc_info[i];
 265
 266        return NULL;
 267}
 268
 269/*
 270 * Try to read the BIOS display configuration and use it for the initial
 271 * fb configuration.
 272 *
 273 * The BIOS or boot loader will generally create an initial display
 274 * configuration for us that includes some set of active pipes and displays.
 275 * This routine tries to figure out which pipes and connectors are active
 276 * and stuffs them into the crtcs and modes array given to us by the
 277 * drm_fb_helper code.
 278 *
 279 * The overall sequence is:
 280 *   intel_fbdev_init - from driver load
 281 *     intel_fbdev_init_bios - initialize the intel_fbdev using BIOS data
 282 *     drm_fb_helper_init - build fb helper structs
 283 *     drm_fb_helper_single_add_all_connectors - more fb helper structs
 284 *   intel_fbdev_initial_config - apply the config
 285 *     drm_fb_helper_initial_config - call ->probe then register_framebuffer()
 286 *         drm_setup_crtcs - build crtc config for fbdev
 287 *           intel_fb_initial_config - find active connectors etc
 288 *         drm_fb_helper_single_fb_probe - set up fbdev
 289 *           intelfb_create - re-use or alloc fb, build out fbdev structs
 290 *
 291 * Note that we don't make special consideration whether we could actually
 292 * switch to the selected modes without a full modeset. E.g. when the display
 293 * is in VGA mode we need to recalculate watermarks and set a new high-res
 294 * framebuffer anyway.
 295 */
 296static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
 297                                    struct drm_fb_helper_crtc **crtcs,
 298                                    struct drm_display_mode **modes,
 299                                    bool *enabled, int width, int height)
 300{
 301        struct drm_device *dev = fb_helper->dev;
 302        int i, j;
 303        bool *save_enabled;
 304        bool fallback = true;
 305        int num_connectors_enabled = 0;
 306        int num_connectors_detected = 0;
 307
 308        /*
 309         * If the user specified any force options, just bail here
 310         * and use that config.
 311         */
 312        for (i = 0; i < fb_helper->connector_count; i++) {
 313                struct drm_fb_helper_connector *fb_conn;
 314                struct drm_connector *connector;
 315
 316                fb_conn = fb_helper->connector_info[i];
 317                connector = fb_conn->connector;
 318
 319                if (!enabled[i])
 320                        continue;
 321
 322                if (connector->force != DRM_FORCE_UNSPECIFIED)
 323                        return false;
 324        }
 325
 326        save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
 327                               GFP_KERNEL);
 328        if (!save_enabled)
 329                return false;
 330
 331        memcpy(save_enabled, enabled, dev->mode_config.num_connector);
 332
 333        for (i = 0; i < fb_helper->connector_count; i++) {
 334                struct drm_fb_helper_connector *fb_conn;
 335                struct drm_connector *connector;
 336                struct drm_encoder *encoder;
 337                struct drm_fb_helper_crtc *new_crtc;
 338
 339                fb_conn = fb_helper->connector_info[i];
 340                connector = fb_conn->connector;
 341
 342                if (connector->status == connector_status_connected)
 343                        num_connectors_detected++;
 344
 345                if (!enabled[i]) {
 346                        DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
 347                                      connector->name);
 348                        continue;
 349                }
 350
 351                encoder = connector->encoder;
 352                if (!encoder || WARN_ON(!encoder->crtc)) {
 353                        DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
 354                                      connector->name);
 355                        enabled[i] = false;
 356                        continue;
 357                }
 358
 359                num_connectors_enabled++;
 360
 361                new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc);
 362
 363                /*
 364                 * Make sure we're not trying to drive multiple connectors
 365                 * with a single CRTC, since our cloning support may not
 366                 * match the BIOS.
 367                 */
 368                for (j = 0; j < fb_helper->connector_count; j++) {
 369                        if (crtcs[j] == new_crtc) {
 370                                DRM_DEBUG_KMS("fallback: cloned configuration\n");
 371                                fallback = true;
 372                                goto out;
 373                        }
 374                }
 375
 376                DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
 377                              connector->name);
 378
 379                /* go for command line mode first */
 380                modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
 381
 382                /* try for preferred next */
 383                if (!modes[i]) {
 384                        DRM_DEBUG_KMS("looking for preferred mode on connector %s\n",
 385                                      connector->name);
 386                        modes[i] = drm_has_preferred_mode(fb_conn, width,
 387                                                          height);
 388                }
 389
 390                /* No preferred mode marked by the EDID? Are there any modes? */
 391                if (!modes[i] && !list_empty(&connector->modes)) {
 392                        DRM_DEBUG_KMS("using first mode listed on connector %s\n",
 393                                      connector->name);
 394                        modes[i] = list_first_entry(&connector->modes,
 395                                                    struct drm_display_mode,
 396                                                    head);
 397                }
 398
 399                /* last resort: use current mode */
 400                if (!modes[i]) {
 401                        /*
 402                         * IMPORTANT: We want to use the adjusted mode (i.e.
 403                         * after the panel fitter upscaling) as the initial
 404                         * config, not the input mode, which is what crtc->mode
 405                         * usually contains. But since our current fastboot
 406                         * code puts a mode derived from the post-pfit timings
 407                         * into crtc->mode this works out correctly. We don't
 408                         * use hwmode anywhere right now, so use it for this
 409                         * since the fb helper layer wants a pointer to
 410                         * something we own.
 411                         */
 412                        DRM_DEBUG_KMS("looking for current mode on connector %s\n",
 413                                      connector->name);
 414                        intel_mode_from_pipe_config(&encoder->crtc->hwmode,
 415                                                    &to_intel_crtc(encoder->crtc)->config);
 416                        modes[i] = &encoder->crtc->hwmode;
 417                }
 418                crtcs[i] = new_crtc;
 419
 420                DRM_DEBUG_KMS("connector %s on pipe %d [CRTC:%d]: %dx%d%s\n",
 421                              connector->name,
 422                              pipe_name(to_intel_crtc(encoder->crtc)->pipe),
 423                              encoder->crtc->base.id,
 424                              modes[i]->hdisplay, modes[i]->vdisplay,
 425                              modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
 426
 427                fallback = false;
 428        }
 429
 430        /*
 431         * If the BIOS didn't enable everything it could, fall back to have the
 432         * same user experiencing of lighting up as much as possible like the
 433         * fbdev helper library.
 434         */
 435        if (num_connectors_enabled != num_connectors_detected &&
 436            num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
 437                DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
 438                DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
 439                              num_connectors_detected);
 440                fallback = true;
 441        }
 442
 443out:
 444        if (fallback) {
 445                DRM_DEBUG_KMS("Not using firmware configuration\n");
 446                memcpy(enabled, save_enabled, dev->mode_config.num_connector);
 447                kfree(save_enabled);
 448                return false;
 449        }
 450
 451        kfree(save_enabled);
 452        return true;
 453}
 454
 455static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
 456        .initial_config = intel_fb_initial_config,
 457        .gamma_set = intel_crtc_fb_gamma_set,
 458        .gamma_get = intel_crtc_fb_gamma_get,
 459        .fb_probe = intelfb_create,
 460};
 461
 462static void intel_fbdev_destroy(struct drm_device *dev,
 463                                struct intel_fbdev *ifbdev)
 464{
 465        if (ifbdev->helper.fbdev) {
 466                struct fb_info *info = ifbdev->helper.fbdev;
 467
 468                unregister_framebuffer(info);
 469                iounmap(info->screen_base);
 470                if (info->cmap.len)
 471                        fb_dealloc_cmap(&info->cmap);
 472
 473                framebuffer_release(info);
 474        }
 475
 476        drm_fb_helper_fini(&ifbdev->helper);
 477
 478        drm_framebuffer_unregister_private(&ifbdev->fb->base);
 479        drm_framebuffer_remove(&ifbdev->fb->base);
 480}
 481
 482/*
 483 * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
 484 * The core display code will have read out the current plane configuration,
 485 * so we use that to figure out if there's an object for us to use as the
 486 * fb, and if so, we re-use it for the fbdev configuration.
 487 *
 488 * Note we only support a single fb shared across pipes for boot (mostly for
 489 * fbcon), so we just find the biggest and use that.
 490 */
 491static bool intel_fbdev_init_bios(struct drm_device *dev,
 492                                 struct intel_fbdev *ifbdev)
 493{
 494        struct intel_framebuffer *fb = NULL;
 495        struct drm_crtc *crtc;
 496        struct intel_crtc *intel_crtc;
 497        struct intel_plane_config *plane_config = NULL;
 498        unsigned int max_size = 0;
 499
 500        if (!i915.fastboot)
 501                return false;
 502
 503        /* Find the largest fb */
 504        for_each_crtc(dev, crtc) {
 505                intel_crtc = to_intel_crtc(crtc);
 506
 507                if (!intel_crtc->active || !crtc->primary->fb) {
 508                        DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
 509                                      pipe_name(intel_crtc->pipe));
 510                        continue;
 511                }
 512
 513                if (intel_crtc->plane_config.size > max_size) {
 514                        DRM_DEBUG_KMS("found possible fb from plane %c\n",
 515                                      pipe_name(intel_crtc->pipe));
 516                        plane_config = &intel_crtc->plane_config;
 517                        fb = to_intel_framebuffer(crtc->primary->fb);
 518                        max_size = plane_config->size;
 519                }
 520        }
 521
 522        if (!fb) {
 523                DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
 524                goto out;
 525        }
 526
 527        /* Now make sure all the pipes will fit into it */
 528        for_each_crtc(dev, crtc) {
 529                unsigned int cur_size;
 530
 531                intel_crtc = to_intel_crtc(crtc);
 532
 533                if (!intel_crtc->active) {
 534                        DRM_DEBUG_KMS("pipe %c not active, skipping\n",
 535                                      pipe_name(intel_crtc->pipe));
 536                        continue;
 537                }
 538
 539                DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
 540                              pipe_name(intel_crtc->pipe));
 541
 542                /*
 543                 * See if the plane fb we found above will fit on this
 544                 * pipe.  Note we need to use the selected fb's pitch and bpp
 545                 * rather than the current pipe's, since they differ.
 546                 */
 547                cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay;
 548                cur_size = cur_size * fb->base.bits_per_pixel / 8;
 549                if (fb->base.pitches[0] < cur_size) {
 550                        DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
 551                                      pipe_name(intel_crtc->pipe),
 552                                      cur_size, fb->base.pitches[0]);
 553                        plane_config = NULL;
 554                        fb = NULL;
 555                        break;
 556                }
 557
 558                cur_size = intel_crtc->config.adjusted_mode.crtc_vdisplay;
 559                cur_size = ALIGN(cur_size, plane_config->tiled ? (IS_GEN2(dev) ? 16 : 8) : 1);
 560                cur_size *= fb->base.pitches[0];
 561                DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
 562                              pipe_name(intel_crtc->pipe),
 563                              intel_crtc->config.adjusted_mode.crtc_hdisplay,
 564                              intel_crtc->config.adjusted_mode.crtc_vdisplay,
 565                              fb->base.bits_per_pixel,
 566                              cur_size);
 567
 568                if (cur_size > max_size) {
 569                        DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
 570                                      pipe_name(intel_crtc->pipe),
 571                                      cur_size, max_size);
 572                        plane_config = NULL;
 573                        fb = NULL;
 574                        break;
 575                }
 576
 577                DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
 578                              pipe_name(intel_crtc->pipe),
 579                              max_size, cur_size);
 580        }
 581
 582        if (!fb) {
 583                DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
 584                goto out;
 585        }
 586
 587        ifbdev->preferred_bpp = fb->base.bits_per_pixel;
 588        ifbdev->fb = fb;
 589
 590        drm_framebuffer_reference(&ifbdev->fb->base);
 591
 592        /* Final pass to check if any active pipes don't have fbs */
 593        for_each_crtc(dev, crtc) {
 594                intel_crtc = to_intel_crtc(crtc);
 595
 596                if (!intel_crtc->active)
 597                        continue;
 598
 599                WARN(!crtc->primary->fb,
 600                     "re-used BIOS config but lost an fb on crtc %d\n",
 601                     crtc->base.id);
 602        }
 603
 604
 605        DRM_DEBUG_KMS("using BIOS fb for initial console\n");
 606        return true;
 607
 608out:
 609
 610        return false;
 611}
 612
 613int intel_fbdev_init(struct drm_device *dev)
 614{
 615        struct intel_fbdev *ifbdev;
 616        struct drm_i915_private *dev_priv = dev->dev_private;
 617        int ret;
 618
 619        if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
 620                return -ENODEV;
 621
 622        ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
 623        if (ifbdev == NULL)
 624                return -ENOMEM;
 625
 626        ifbdev->helper.funcs = &intel_fb_helper_funcs;
 627        if (!intel_fbdev_init_bios(dev, ifbdev))
 628                ifbdev->preferred_bpp = 32;
 629
 630        ret = drm_fb_helper_init(dev, &ifbdev->helper,
 631                                 INTEL_INFO(dev)->num_pipes, 4);
 632        if (ret) {
 633                kfree(ifbdev);
 634                return ret;
 635        }
 636
 637        dev_priv->fbdev = ifbdev;
 638        drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
 639
 640        return 0;
 641}
 642
 643void intel_fbdev_initial_config(struct drm_device *dev)
 644{
 645        struct drm_i915_private *dev_priv = dev->dev_private;
 646        struct intel_fbdev *ifbdev = dev_priv->fbdev;
 647
 648        /* Due to peculiar init order wrt to hpd handling this is separate. */
 649        drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp);
 650}
 651
 652void intel_fbdev_fini(struct drm_device *dev)
 653{
 654        struct drm_i915_private *dev_priv = dev->dev_private;
 655        if (!dev_priv->fbdev)
 656                return;
 657
 658        intel_fbdev_destroy(dev, dev_priv->fbdev);
 659        kfree(dev_priv->fbdev);
 660        dev_priv->fbdev = NULL;
 661}
 662
 663void intel_fbdev_set_suspend(struct drm_device *dev, int state)
 664{
 665        struct drm_i915_private *dev_priv = dev->dev_private;
 666        struct intel_fbdev *ifbdev = dev_priv->fbdev;
 667        struct fb_info *info;
 668
 669        if (!ifbdev)
 670                return;
 671
 672        info = ifbdev->helper.fbdev;
 673
 674        /* On resume from hibernation: If the object is shmemfs backed, it has
 675         * been restored from swap. If the object is stolen however, it will be
 676         * full of whatever garbage was left in there.
 677         */
 678        if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
 679                memset_io(info->screen_base, 0, info->screen_size);
 680
 681        fb_set_suspend(info, state);
 682}
 683
 684void intel_fbdev_output_poll_changed(struct drm_device *dev)
 685{
 686        struct drm_i915_private *dev_priv = dev->dev_private;
 687        if (dev_priv->fbdev)
 688                drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
 689}
 690
 691void intel_fbdev_restore_mode(struct drm_device *dev)
 692{
 693        int ret;
 694        struct drm_i915_private *dev_priv = dev->dev_private;
 695
 696        if (!dev_priv->fbdev)
 697                return;
 698
 699        ret = drm_fb_helper_restore_fbdev_mode_unlocked(&dev_priv->fbdev->helper);
 700        if (ret)
 701                DRM_DEBUG("failed to restore crtc mode\n");
 702}
 703