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/console.h> 28 #include <linux/delay.h> 29 #include <linux/errno.h> 30 #include <linux/fb.h> 31 #include <linux/init.h> 32 #include <linux/kernel.h> 33 #include <linux/mm.h> 34 #include <linux/module.h> 35 #include <linux/string.h> 36 #include <linux/sysrq.h> 37 #include <linux/tty.h> 38 #include <linux/vga_switcheroo.h> 39 40 #include <drm/drm_crtc.h> 41 #include <drm/drm_crtc_helper.h> 42 #include <drm/drm_fb_helper.h> 43 #include <drm/drm_fourcc.h> 44 #include <drm/drm_gem.h> 45 #include <drm/drm_gem_framebuffer_helper.h> 46 47 #include "i915_drv.h" 48 #include "intel_bo.h" 49 #include "intel_display_types.h" 50 #include "intel_fb.h" 51 #include "intel_fb_pin.h" 52 #include "intel_fbdev.h" 53 #include "intel_fbdev_fb.h" 54 #include "intel_frontbuffer.h" 55 56 struct intel_fbdev { 57 struct drm_fb_helper helper; 58 struct intel_framebuffer *fb; 59 struct i915_vma *vma; 60 unsigned long vma_flags; 61 int preferred_bpp; 62 63 /* Whether or not fbdev hpd processing is temporarily suspended */ 64 bool hpd_suspended: 1; 65 /* Set when a hotplug was received while HPD processing was suspended */ 66 bool hpd_waiting: 1; 67 68 /* Protects hpd_suspended */ 69 struct mutex hpd_lock; 70 }; 71 72 static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) 73 { 74 return container_of(fb_helper, struct intel_fbdev, helper); 75 } 76 77 static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) 78 { 79 return ifbdev->fb->frontbuffer; 80 } 81 82 static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) 83 { 84 intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU); 85 } 86 87 FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(intel_fbdev, 88 drm_fb_helper_damage_range, 89 drm_fb_helper_damage_area) 90 91 static int intel_fbdev_set_par(struct fb_info *info) 92 { 93 struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); 94 int ret; 95 96 ret = drm_fb_helper_set_par(info); 97 if (ret == 0) 98 intel_fbdev_invalidate(ifbdev); 99 100 return ret; 101 } 102 103 static int intel_fbdev_blank(int blank, struct fb_info *info) 104 { 105 struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); 106 int ret; 107 108 ret = drm_fb_helper_blank(blank, info); 109 if (ret == 0) 110 intel_fbdev_invalidate(ifbdev); 111 112 return ret; 113 } 114 115 static int intel_fbdev_pan_display(struct fb_var_screeninfo *var, 116 struct fb_info *info) 117 { 118 struct intel_fbdev *ifbdev = to_intel_fbdev(info->par); 119 int ret; 120 121 ret = drm_fb_helper_pan_display(var, info); 122 if (ret == 0) 123 intel_fbdev_invalidate(ifbdev); 124 125 return ret; 126 } 127 128 static int intel_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) 129 { 130 struct intel_fbdev *fbdev = to_intel_fbdev(info->par); 131 struct drm_gem_object *obj = drm_gem_fb_get_obj(&fbdev->fb->base, 0); 132 133 return intel_bo_fb_mmap(obj, vma); 134 } 135 136 static void intel_fbdev_fb_destroy(struct fb_info *info) 137 { 138 struct drm_fb_helper *fb_helper = info->par; 139 struct intel_fbdev *ifbdev = container_of(fb_helper, struct intel_fbdev, helper); 140 141 drm_fb_helper_fini(&ifbdev->helper); 142 143 /* 144 * We rely on the object-free to release the VMA pinning for 145 * the info->screen_base mmaping. Leaking the VMA is simpler than 146 * trying to rectify all the possible error paths leading here. 147 */ 148 intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags); 149 drm_framebuffer_remove(&ifbdev->fb->base); 150 151 drm_client_release(&fb_helper->client); 152 drm_fb_helper_unprepare(&ifbdev->helper); 153 kfree(ifbdev); 154 } 155 156 __diag_push(); 157 __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for fb ops"); 158 159 static const struct fb_ops intelfb_ops = { 160 .owner = THIS_MODULE, 161 __FB_DEFAULT_DEFERRED_OPS_RDWR(intel_fbdev), 162 DRM_FB_HELPER_DEFAULT_OPS, 163 .fb_set_par = intel_fbdev_set_par, 164 .fb_blank = intel_fbdev_blank, 165 .fb_pan_display = intel_fbdev_pan_display, 166 __FB_DEFAULT_DEFERRED_OPS_DRAW(intel_fbdev), 167 .fb_mmap = intel_fbdev_mmap, 168 .fb_destroy = intel_fbdev_fb_destroy, 169 }; 170 171 __diag_pop(); 172 173 static int intelfb_create(struct drm_fb_helper *helper, 174 struct drm_fb_helper_surface_size *sizes) 175 { 176 struct intel_fbdev *ifbdev = to_intel_fbdev(helper); 177 struct intel_framebuffer *fb = ifbdev->fb; 178 struct drm_device *dev = helper->dev; 179 struct drm_i915_private *dev_priv = to_i915(dev); 180 intel_wakeref_t wakeref; 181 struct fb_info *info; 182 struct i915_vma *vma; 183 unsigned long flags = 0; 184 bool prealloc = false; 185 struct drm_gem_object *obj; 186 int ret; 187 188 mutex_lock(&ifbdev->hpd_lock); 189 ret = ifbdev->hpd_suspended ? -EAGAIN : 0; 190 mutex_unlock(&ifbdev->hpd_lock); 191 if (ret) 192 return ret; 193 194 ifbdev->fb = NULL; 195 196 if (fb && 197 (sizes->fb_width > fb->base.width || 198 sizes->fb_height > fb->base.height)) { 199 drm_dbg_kms(&dev_priv->drm, 200 "BIOS fb too small (%dx%d), we require (%dx%d)," 201 " releasing it\n", 202 fb->base.width, fb->base.height, 203 sizes->fb_width, sizes->fb_height); 204 drm_framebuffer_put(&fb->base); 205 fb = NULL; 206 } 207 if (!fb || drm_WARN_ON(dev, !intel_fb_bo(&fb->base))) { 208 drm_dbg_kms(&dev_priv->drm, 209 "no BIOS fb, allocating a new one\n"); 210 fb = intel_fbdev_fb_alloc(helper, sizes); 211 if (IS_ERR(fb)) 212 return PTR_ERR(fb); 213 } else { 214 drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n"); 215 prealloc = true; 216 sizes->fb_width = fb->base.width; 217 sizes->fb_height = fb->base.height; 218 } 219 220 wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); 221 222 /* Pin the GGTT vma for our access via info->screen_base. 223 * This also validates that any existing fb inherited from the 224 * BIOS is suitable for own access. 225 */ 226 vma = intel_fb_pin_to_ggtt(&fb->base, &fb->normal_view.gtt, 227 fb->min_alignment, 0, 228 intel_fb_view_vtd_guard(&fb->base, &fb->normal_view, 229 DRM_MODE_ROTATE_0), 230 false, &flags); 231 if (IS_ERR(vma)) { 232 ret = PTR_ERR(vma); 233 goto out_unlock; 234 } 235 236 info = drm_fb_helper_alloc_info(helper); 237 if (IS_ERR(info)) { 238 drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info); 239 ret = PTR_ERR(info); 240 goto out_unpin; 241 } 242 243 ifbdev->helper.fb = &fb->base; 244 245 info->fbops = &intelfb_ops; 246 247 obj = intel_fb_bo(&fb->base); 248 249 ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma); 250 if (ret) 251 goto out_unpin; 252 253 drm_fb_helper_fill_info(info, &ifbdev->helper, sizes); 254 255 /* If the object is shmemfs backed, it will have given us zeroed pages. 256 * If the object is stolen however, it will be full of whatever 257 * garbage was left in there. 258 */ 259 if (!intel_bo_is_shmem(obj) && !prealloc) 260 memset_io(info->screen_base, 0, info->screen_size); 261 262 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ 263 264 drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n", 265 fb->base.width, fb->base.height, 266 i915_ggtt_offset(vma)); 267 ifbdev->fb = fb; 268 ifbdev->vma = vma; 269 ifbdev->vma_flags = flags; 270 271 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); 272 273 return 0; 274 275 out_unpin: 276 intel_fb_unpin_vma(vma, flags); 277 out_unlock: 278 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); 279 return ret; 280 } 281 282 static int intelfb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) 283 { 284 if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) 285 return 0; 286 287 if (helper->fb->funcs->dirty) 288 return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); 289 290 return 0; 291 } 292 293 static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { 294 .fb_probe = intelfb_create, 295 .fb_dirty = intelfb_dirty, 296 }; 297 298 /* 299 * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible. 300 * The core display code will have read out the current plane configuration, 301 * so we use that to figure out if there's an object for us to use as the 302 * fb, and if so, we re-use it for the fbdev configuration. 303 * 304 * Note we only support a single fb shared across pipes for boot (mostly for 305 * fbcon), so we just find the biggest and use that. 306 */ 307 static bool intel_fbdev_init_bios(struct drm_device *dev, 308 struct intel_fbdev *ifbdev) 309 { 310 struct drm_i915_private *i915 = to_i915(dev); 311 struct intel_framebuffer *fb = NULL; 312 struct intel_crtc *crtc; 313 unsigned int max_size = 0; 314 315 /* Find the largest fb */ 316 for_each_intel_crtc(dev, crtc) { 317 struct intel_crtc_state *crtc_state = 318 to_intel_crtc_state(crtc->base.state); 319 struct intel_plane *plane = 320 to_intel_plane(crtc->base.primary); 321 struct intel_plane_state *plane_state = 322 to_intel_plane_state(plane->base.state); 323 struct drm_gem_object *obj = intel_fb_bo(plane_state->uapi.fb); 324 325 if (!crtc_state->uapi.active) { 326 drm_dbg_kms(&i915->drm, 327 "[CRTC:%d:%s] not active, skipping\n", 328 crtc->base.base.id, crtc->base.name); 329 continue; 330 } 331 332 if (!obj) { 333 drm_dbg_kms(&i915->drm, 334 "[PLANE:%d:%s] no fb, skipping\n", 335 plane->base.base.id, plane->base.name); 336 continue; 337 } 338 339 if (obj->size > max_size) { 340 drm_dbg_kms(&i915->drm, 341 "found possible fb from [PLANE:%d:%s]\n", 342 plane->base.base.id, plane->base.name); 343 fb = to_intel_framebuffer(plane_state->uapi.fb); 344 max_size = obj->size; 345 } 346 } 347 348 if (!fb) { 349 drm_dbg_kms(&i915->drm, 350 "no active fbs found, not using BIOS config\n"); 351 goto out; 352 } 353 354 /* Now make sure all the pipes will fit into it */ 355 for_each_intel_crtc(dev, crtc) { 356 struct intel_crtc_state *crtc_state = 357 to_intel_crtc_state(crtc->base.state); 358 struct intel_plane *plane = 359 to_intel_plane(crtc->base.primary); 360 unsigned int cur_size; 361 362 if (!crtc_state->uapi.active) { 363 drm_dbg_kms(&i915->drm, 364 "[CRTC:%d:%s] not active, skipping\n", 365 crtc->base.base.id, crtc->base.name); 366 continue; 367 } 368 369 drm_dbg_kms(&i915->drm, "checking [PLANE:%d:%s] for BIOS fb\n", 370 plane->base.base.id, plane->base.name); 371 372 /* 373 * See if the plane fb we found above will fit on this 374 * pipe. Note we need to use the selected fb's pitch and bpp 375 * rather than the current pipe's, since they differ. 376 */ 377 cur_size = crtc_state->uapi.adjusted_mode.crtc_hdisplay; 378 cur_size = cur_size * fb->base.format->cpp[0]; 379 if (fb->base.pitches[0] < cur_size) { 380 drm_dbg_kms(&i915->drm, 381 "fb not wide enough for [PLANE:%d:%s] (%d vs %d)\n", 382 plane->base.base.id, plane->base.name, 383 cur_size, fb->base.pitches[0]); 384 fb = NULL; 385 break; 386 } 387 388 cur_size = crtc_state->uapi.adjusted_mode.crtc_vdisplay; 389 cur_size = intel_fb_align_height(&fb->base, 0, cur_size); 390 cur_size *= fb->base.pitches[0]; 391 drm_dbg_kms(&i915->drm, 392 "[CRTC:%d:%s] area: %dx%d, bpp: %d, size: %d\n", 393 crtc->base.base.id, crtc->base.name, 394 crtc_state->uapi.adjusted_mode.crtc_hdisplay, 395 crtc_state->uapi.adjusted_mode.crtc_vdisplay, 396 fb->base.format->cpp[0] * 8, 397 cur_size); 398 399 if (cur_size > max_size) { 400 drm_dbg_kms(&i915->drm, 401 "fb not big enough for [PLANE:%d:%s] (%d vs %d)\n", 402 plane->base.base.id, plane->base.name, 403 cur_size, max_size); 404 fb = NULL; 405 break; 406 } 407 408 drm_dbg_kms(&i915->drm, 409 "fb big enough [PLANE:%d:%s] (%d >= %d)\n", 410 plane->base.base.id, plane->base.name, 411 max_size, cur_size); 412 } 413 414 if (!fb) { 415 drm_dbg_kms(&i915->drm, 416 "BIOS fb not suitable for all pipes, not using\n"); 417 goto out; 418 } 419 420 ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8; 421 ifbdev->fb = fb; 422 423 drm_framebuffer_get(&ifbdev->fb->base); 424 425 /* Final pass to check if any active pipes don't have fbs */ 426 for_each_intel_crtc(dev, crtc) { 427 struct intel_crtc_state *crtc_state = 428 to_intel_crtc_state(crtc->base.state); 429 struct intel_plane *plane = 430 to_intel_plane(crtc->base.primary); 431 struct intel_plane_state *plane_state = 432 to_intel_plane_state(plane->base.state); 433 434 if (!crtc_state->uapi.active) 435 continue; 436 437 drm_WARN(dev, !plane_state->uapi.fb, 438 "re-used BIOS config but lost an fb on [PLANE:%d:%s]\n", 439 plane->base.base.id, plane->base.name); 440 } 441 442 443 drm_dbg_kms(&i915->drm, "using BIOS fb for initial console\n"); 444 return true; 445 446 out: 447 448 return false; 449 } 450 451 static void intel_fbdev_suspend_worker(struct work_struct *work) 452 { 453 intel_fbdev_set_suspend(&container_of(work, 454 struct drm_i915_private, 455 display.fbdev.suspend_work)->drm, 456 FBINFO_STATE_RUNNING, 457 true); 458 } 459 460 /* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD 461 * processing, fbdev will perform a full connector reprobe if a hotplug event 462 * was received while HPD was suspended. 463 */ 464 static void intel_fbdev_hpd_set_suspend(struct drm_i915_private *i915, int state) 465 { 466 struct intel_fbdev *ifbdev = i915->display.fbdev.fbdev; 467 bool send_hpd = false; 468 469 mutex_lock(&ifbdev->hpd_lock); 470 ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED; 471 send_hpd = !ifbdev->hpd_suspended && ifbdev->hpd_waiting; 472 ifbdev->hpd_waiting = false; 473 mutex_unlock(&ifbdev->hpd_lock); 474 475 if (send_hpd) { 476 drm_dbg_kms(&i915->drm, "Handling delayed fbcon HPD event\n"); 477 drm_fb_helper_hotplug_event(&ifbdev->helper); 478 } 479 } 480 481 void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) 482 { 483 struct drm_i915_private *dev_priv = to_i915(dev); 484 struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; 485 struct fb_info *info; 486 487 if (!ifbdev) 488 return; 489 490 if (drm_WARN_ON(&dev_priv->drm, !HAS_DISPLAY(dev_priv))) 491 return; 492 493 if (!ifbdev->vma) 494 goto set_suspend; 495 496 info = ifbdev->helper.info; 497 498 if (synchronous) { 499 /* Flush any pending work to turn the console on, and then 500 * wait to turn it off. It must be synchronous as we are 501 * about to suspend or unload the driver. 502 * 503 * Note that from within the work-handler, we cannot flush 504 * ourselves, so only flush outstanding work upon suspend! 505 */ 506 if (state != FBINFO_STATE_RUNNING) 507 flush_work(&dev_priv->display.fbdev.suspend_work); 508 509 console_lock(); 510 } else { 511 /* 512 * The console lock can be pretty contented on resume due 513 * to all the printk activity. Try to keep it out of the hot 514 * path of resume if possible. 515 */ 516 drm_WARN_ON(dev, state != FBINFO_STATE_RUNNING); 517 if (!console_trylock()) { 518 /* Don't block our own workqueue as this can 519 * be run in parallel with other i915.ko tasks. 520 */ 521 queue_work(dev_priv->unordered_wq, 522 &dev_priv->display.fbdev.suspend_work); 523 return; 524 } 525 } 526 527 /* On resume from hibernation: If the object is shmemfs backed, it has 528 * been restored from swap. If the object is stolen however, it will be 529 * full of whatever garbage was left in there. 530 */ 531 if (state == FBINFO_STATE_RUNNING && 532 !intel_bo_is_shmem(intel_fb_bo(&ifbdev->fb->base))) 533 memset_io(info->screen_base, 0, info->screen_size); 534 535 drm_fb_helper_set_suspend(&ifbdev->helper, state); 536 console_unlock(); 537 538 set_suspend: 539 intel_fbdev_hpd_set_suspend(dev_priv, state); 540 } 541 542 static int intel_fbdev_output_poll_changed(struct drm_device *dev) 543 { 544 struct intel_fbdev *ifbdev = to_i915(dev)->display.fbdev.fbdev; 545 bool send_hpd; 546 547 if (!ifbdev) 548 return -EINVAL; 549 550 mutex_lock(&ifbdev->hpd_lock); 551 send_hpd = !ifbdev->hpd_suspended; 552 ifbdev->hpd_waiting = true; 553 mutex_unlock(&ifbdev->hpd_lock); 554 555 if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup)) 556 drm_fb_helper_hotplug_event(&ifbdev->helper); 557 558 return 0; 559 } 560 561 static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) 562 { 563 struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; 564 int ret; 565 566 if (!ifbdev) 567 return -EINVAL; 568 569 if (!ifbdev->vma) 570 return -ENOMEM; 571 572 ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper); 573 if (ret) 574 return ret; 575 576 intel_fbdev_invalidate(ifbdev); 577 578 return 0; 579 } 580 581 /* 582 * Fbdev client and struct drm_client_funcs 583 */ 584 585 static void intel_fbdev_client_unregister(struct drm_client_dev *client) 586 { 587 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 588 struct drm_device *dev = fb_helper->dev; 589 struct pci_dev *pdev = to_pci_dev(dev->dev); 590 591 if (fb_helper->info) { 592 vga_switcheroo_client_fb_set(pdev, NULL); 593 drm_fb_helper_unregister_info(fb_helper); 594 } else { 595 drm_fb_helper_unprepare(fb_helper); 596 drm_client_release(&fb_helper->client); 597 kfree(fb_helper); 598 } 599 } 600 601 static int intel_fbdev_client_restore(struct drm_client_dev *client) 602 { 603 struct drm_i915_private *dev_priv = to_i915(client->dev); 604 int ret; 605 606 ret = intel_fbdev_restore_mode(dev_priv); 607 if (ret) 608 return ret; 609 610 vga_switcheroo_process_delayed_switch(); 611 612 return 0; 613 } 614 615 static int intel_fbdev_client_hotplug(struct drm_client_dev *client) 616 { 617 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 618 struct drm_device *dev = client->dev; 619 struct pci_dev *pdev = to_pci_dev(dev->dev); 620 int ret; 621 622 if (dev->fb_helper) 623 return intel_fbdev_output_poll_changed(dev); 624 625 ret = drm_fb_helper_init(dev, fb_helper); 626 if (ret) 627 goto err_drm_err; 628 629 ret = drm_fb_helper_initial_config(fb_helper); 630 if (ret) 631 goto err_drm_fb_helper_fini; 632 633 vga_switcheroo_client_fb_set(pdev, fb_helper->info); 634 635 return 0; 636 637 err_drm_fb_helper_fini: 638 drm_fb_helper_fini(fb_helper); 639 err_drm_err: 640 drm_err(dev, "Failed to setup i915 fbdev emulation (ret=%d)\n", ret); 641 return ret; 642 } 643 644 static const struct drm_client_funcs intel_fbdev_client_funcs = { 645 .owner = THIS_MODULE, 646 .unregister = intel_fbdev_client_unregister, 647 .restore = intel_fbdev_client_restore, 648 .hotplug = intel_fbdev_client_hotplug, 649 }; 650 651 void intel_fbdev_setup(struct drm_i915_private *i915) 652 { 653 struct drm_device *dev = &i915->drm; 654 struct intel_fbdev *ifbdev; 655 int ret; 656 657 if (!HAS_DISPLAY(i915)) 658 return; 659 660 ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); 661 if (!ifbdev) 662 return; 663 drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs); 664 665 i915->display.fbdev.fbdev = ifbdev; 666 INIT_WORK(&i915->display.fbdev.suspend_work, intel_fbdev_suspend_worker); 667 mutex_init(&ifbdev->hpd_lock); 668 if (intel_fbdev_init_bios(dev, ifbdev)) 669 ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp; 670 else 671 ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp; 672 673 ret = drm_client_init(dev, &ifbdev->helper.client, "intel-fbdev", 674 &intel_fbdev_client_funcs); 675 if (ret) { 676 drm_err(dev, "Failed to register client: %d\n", ret); 677 goto err_drm_fb_helper_unprepare; 678 } 679 680 drm_client_register(&ifbdev->helper.client); 681 682 return; 683 684 err_drm_fb_helper_unprepare: 685 drm_fb_helper_unprepare(&ifbdev->helper); 686 mutex_destroy(&ifbdev->hpd_lock); 687 kfree(ifbdev); 688 } 689 690 struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) 691 { 692 if (!fbdev || !fbdev->helper.fb) 693 return NULL; 694 695 return to_intel_framebuffer(fbdev->helper.fb); 696 } 697 698 struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) 699 { 700 return fbdev ? fbdev->vma : NULL; 701 } 702