aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbdev.c')
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c390
1 files changed, 370 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 39eac9937a4a..f73ba5e6b7a8 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -62,6 +62,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
62{ 62{
63 struct intel_fbdev *ifbdev = 63 struct intel_fbdev *ifbdev =
64 container_of(helper, struct intel_fbdev, helper); 64 container_of(helper, struct intel_fbdev, helper);
65 struct drm_framebuffer *fb;
65 struct drm_device *dev = helper->dev; 66 struct drm_device *dev = helper->dev;
66 struct drm_mode_fb_cmd2 mode_cmd = {}; 67 struct drm_mode_fb_cmd2 mode_cmd = {};
67 struct drm_i915_gem_object *obj; 68 struct drm_i915_gem_object *obj;
@@ -93,18 +94,22 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
93 /* Flush everything out, we'll be doing GTT only from now on */ 94 /* Flush everything out, we'll be doing GTT only from now on */
94 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); 95 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
95 if (ret) { 96 if (ret) {
96 DRM_ERROR("failed to pin fb: %d\n", ret); 97 DRM_ERROR("failed to pin obj: %d\n", ret);
97 goto out_unref; 98 goto out_unref;
98 } 99 }
99 100
100 ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); 101 fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
101 if (ret) 102 if (IS_ERR(fb)) {
103 ret = PTR_ERR(fb);
102 goto out_unpin; 104 goto out_unpin;
105 }
106
107 ifbdev->fb = to_intel_framebuffer(fb);
103 108
104 return 0; 109 return 0;
105 110
106out_unpin: 111out_unpin:
107 i915_gem_object_unpin(obj); 112 i915_gem_object_ggtt_unpin(obj);
108out_unref: 113out_unref:
109 drm_gem_object_unreference(&obj->base); 114 drm_gem_object_unreference(&obj->base);
110out: 115out:
@@ -116,23 +121,36 @@ static int intelfb_create(struct drm_fb_helper *helper,
116{ 121{
117 struct intel_fbdev *ifbdev = 122 struct intel_fbdev *ifbdev =
118 container_of(helper, struct intel_fbdev, helper); 123 container_of(helper, struct intel_fbdev, helper);
119 struct intel_framebuffer *intel_fb = &ifbdev->ifb; 124 struct intel_framebuffer *intel_fb = ifbdev->fb;
120 struct drm_device *dev = helper->dev; 125 struct drm_device *dev = helper->dev;
121 struct drm_i915_private *dev_priv = dev->dev_private; 126 struct drm_i915_private *dev_priv = dev->dev_private;
122 struct fb_info *info; 127 struct fb_info *info;
123 struct drm_framebuffer *fb; 128 struct drm_framebuffer *fb;
124 struct drm_i915_gem_object *obj; 129 struct drm_i915_gem_object *obj;
125 int size, ret; 130 int size, ret;
131 bool prealloc = false;
126 132
127 mutex_lock(&dev->struct_mutex); 133 mutex_lock(&dev->struct_mutex);
128 134
129 if (!intel_fb->obj) { 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)) {
130 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); 146 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
131 ret = intelfb_alloc(helper, sizes); 147 ret = intelfb_alloc(helper, sizes);
132 if (ret) 148 if (ret)
133 goto out_unlock; 149 goto out_unlock;
150 intel_fb = ifbdev->fb;
134 } else { 151 } else {
135 DRM_DEBUG_KMS("re-using BIOS fb\n"); 152 DRM_DEBUG_KMS("re-using BIOS fb\n");
153 prealloc = true;
136 sizes->fb_width = intel_fb->base.width; 154 sizes->fb_width = intel_fb->base.width;
137 sizes->fb_height = intel_fb->base.height; 155 sizes->fb_height = intel_fb->base.height;
138 } 156 }
@@ -148,7 +166,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
148 166
149 info->par = helper; 167 info->par = helper;
150 168
151 fb = &ifbdev->ifb.base; 169 fb = &ifbdev->fb->base;
152 170
153 ifbdev->helper.fb = fb; 171 ifbdev->helper.fb = fb;
154 ifbdev->helper.fbdev = info; 172 ifbdev->helper.fbdev = info;
@@ -194,7 +212,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
194 * If the object is stolen however, it will be full of whatever 212 * If the object is stolen however, it will be full of whatever
195 * garbage was left in there. 213 * garbage was left in there.
196 */ 214 */
197 if (ifbdev->ifb.obj->stolen) 215 if (ifbdev->fb->obj->stolen && !prealloc)
198 memset_io(info->screen_base, 0, info->screen_size); 216 memset_io(info->screen_base, 0, info->screen_size);
199 217
200 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ 218 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
@@ -208,7 +226,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
208 return 0; 226 return 0;
209 227
210out_unpin: 228out_unpin:
211 i915_gem_object_unpin(obj); 229 i915_gem_object_ggtt_unpin(obj);
212 drm_gem_object_unreference(&obj->base); 230 drm_gem_object_unreference(&obj->base);
213out_unlock: 231out_unlock:
214 mutex_unlock(&dev->struct_mutex); 232 mutex_unlock(&dev->struct_mutex);
@@ -236,7 +254,202 @@ static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
236 *blue = intel_crtc->lut_b[regno] << 8; 254 *blue = intel_crtc->lut_b[regno] << 8;
237} 255}
238 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 %d not enabled, skipping\n",
347 connector->base.id);
348 continue;
349 }
350
351 encoder = connector->encoder;
352 if (!encoder || WARN_ON(!encoder->crtc)) {
353 DRM_DEBUG_KMS("connector %d has no encoder or crtc, skipping\n",
354 connector->base.id);
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 %d\n",
377 fb_conn->connector->base.id);
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 %d\n",
385 fb_conn->connector->base.id);
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 drm_get_connector_name(connector));
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 intel_mode_from_pipe_config(&encoder->crtc->hwmode,
413 &to_intel_crtc(encoder->crtc)->config);
414 modes[i] = &encoder->crtc->hwmode;
415 }
416 crtcs[i] = new_crtc;
417
418 DRM_DEBUG_KMS("connector %s on crtc %d: %s\n",
419 drm_get_connector_name(connector),
420 encoder->crtc->base.id,
421 modes[i]->name);
422
423 fallback = false;
424 }
425
426 /*
427 * If the BIOS didn't enable everything it could, fall back to have the
428 * same user experiencing of lighting up as much as possible like the
429 * fbdev helper library.
430 */
431 if (num_connectors_enabled != num_connectors_detected &&
432 num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
433 DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
434 DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
435 num_connectors_detected);
436 fallback = true;
437 }
438
439out:
440 if (fallback) {
441 DRM_DEBUG_KMS("Not using firmware configuration\n");
442 memcpy(enabled, save_enabled, dev->mode_config.num_connector);
443 kfree(save_enabled);
444 return false;
445 }
446
447 kfree(save_enabled);
448 return true;
449}
450
239static struct drm_fb_helper_funcs intel_fb_helper_funcs = { 451static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
452 .initial_config = intel_fb_initial_config,
240 .gamma_set = intel_crtc_fb_gamma_set, 453 .gamma_set = intel_crtc_fb_gamma_set,
241 .gamma_get = intel_crtc_fb_gamma_get, 454 .gamma_get = intel_crtc_fb_gamma_get,
242 .fb_probe = intelfb_create, 455 .fb_probe = intelfb_create,
@@ -258,8 +471,139 @@ static void intel_fbdev_destroy(struct drm_device *dev,
258 471
259 drm_fb_helper_fini(&ifbdev->helper); 472 drm_fb_helper_fini(&ifbdev->helper);
260 473
261 drm_framebuffer_unregister_private(&ifbdev->ifb.base); 474 drm_framebuffer_unregister_private(&ifbdev->fb->base);
262 intel_framebuffer_fini(&ifbdev->ifb); 475 drm_framebuffer_remove(&ifbdev->fb->base);
476}
477
478/*
479 * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
480 * The core display code will have read out the current plane configuration,
481 * so we use that to figure out if there's an object for us to use as the
482 * fb, and if so, we re-use it for the fbdev configuration.
483 *
484 * Note we only support a single fb shared across pipes for boot (mostly for
485 * fbcon), so we just find the biggest and use that.
486 */
487static bool intel_fbdev_init_bios(struct drm_device *dev,
488 struct intel_fbdev *ifbdev)
489{
490 struct intel_framebuffer *fb = NULL;
491 struct drm_crtc *crtc;
492 struct intel_crtc *intel_crtc;
493 struct intel_plane_config *plane_config = NULL;
494 unsigned int max_size = 0;
495
496 if (!i915.fastboot)
497 return false;
498
499 /* Find the largest fb */
500 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
501 intel_crtc = to_intel_crtc(crtc);
502
503 if (!intel_crtc->active || !crtc->primary->fb) {
504 DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
505 pipe_name(intel_crtc->pipe));
506 continue;
507 }
508
509 if (intel_crtc->plane_config.size > max_size) {
510 DRM_DEBUG_KMS("found possible fb from plane %c\n",
511 pipe_name(intel_crtc->pipe));
512 plane_config = &intel_crtc->plane_config;
513 fb = to_intel_framebuffer(crtc->primary->fb);
514 max_size = plane_config->size;
515 }
516 }
517
518 if (!fb) {
519 DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
520 goto out;
521 }
522
523 /* Now make sure all the pipes will fit into it */
524 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
525 unsigned int cur_size;
526
527 intel_crtc = to_intel_crtc(crtc);
528
529 if (!intel_crtc->active) {
530 DRM_DEBUG_KMS("pipe %c not active, skipping\n",
531 pipe_name(intel_crtc->pipe));
532 continue;
533 }
534
535 DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
536 pipe_name(intel_crtc->pipe));
537
538 /*
539 * See if the plane fb we found above will fit on this
540 * pipe. Note we need to use the selected fb's pitch and bpp
541 * rather than the current pipe's, since they differ.
542 */
543 cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay;
544 cur_size = cur_size * fb->base.bits_per_pixel / 8;
545 if (fb->base.pitches[0] < cur_size) {
546 DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
547 pipe_name(intel_crtc->pipe),
548 cur_size, fb->base.pitches[0]);
549 plane_config = NULL;
550 fb = NULL;
551 break;
552 }
553
554 cur_size = intel_crtc->config.adjusted_mode.crtc_vdisplay;
555 cur_size = ALIGN(cur_size, plane_config->tiled ? (IS_GEN2(dev) ? 16 : 8) : 1);
556 cur_size *= fb->base.pitches[0];
557 DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
558 pipe_name(intel_crtc->pipe),
559 intel_crtc->config.adjusted_mode.crtc_hdisplay,
560 intel_crtc->config.adjusted_mode.crtc_vdisplay,
561 fb->base.bits_per_pixel,
562 cur_size);
563
564 if (cur_size > max_size) {
565 DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
566 pipe_name(intel_crtc->pipe),
567 cur_size, max_size);
568 plane_config = NULL;
569 fb = NULL;
570 break;
571 }
572
573 DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
574 pipe_name(intel_crtc->pipe),
575 max_size, cur_size);
576 }
577
578 if (!fb) {
579 DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
580 goto out;
581 }
582
583 ifbdev->preferred_bpp = fb->base.bits_per_pixel;
584 ifbdev->fb = fb;
585
586 drm_framebuffer_reference(&ifbdev->fb->base);
587
588 /* Final pass to check if any active pipes don't have fbs */
589 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
590 intel_crtc = to_intel_crtc(crtc);
591
592 if (!intel_crtc->active)
593 continue;
594
595 WARN(!crtc->primary->fb,
596 "re-used BIOS config but lost an fb on crtc %d\n",
597 crtc->base.id);
598 }
599
600
601 DRM_DEBUG_KMS("using BIOS fb for initial console\n");
602 return true;
603
604out:
605
606 return false;
263} 607}
264 608
265int intel_fbdev_init(struct drm_device *dev) 609int intel_fbdev_init(struct drm_device *dev)
@@ -268,21 +612,25 @@ int intel_fbdev_init(struct drm_device *dev)
268 struct drm_i915_private *dev_priv = dev->dev_private; 612 struct drm_i915_private *dev_priv = dev->dev_private;
269 int ret; 613 int ret;
270 614
271 ifbdev = kzalloc(sizeof(*ifbdev), GFP_KERNEL); 615 if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
272 if (!ifbdev) 616 return -ENODEV;
617
618 ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
619 if (ifbdev == NULL)
273 return -ENOMEM; 620 return -ENOMEM;
274 621
275 dev_priv->fbdev = ifbdev;
276 ifbdev->helper.funcs = &intel_fb_helper_funcs; 622 ifbdev->helper.funcs = &intel_fb_helper_funcs;
623 if (!intel_fbdev_init_bios(dev, ifbdev))
624 ifbdev->preferred_bpp = 32;
277 625
278 ret = drm_fb_helper_init(dev, &ifbdev->helper, 626 ret = drm_fb_helper_init(dev, &ifbdev->helper,
279 INTEL_INFO(dev)->num_pipes, 627 INTEL_INFO(dev)->num_pipes, 4);
280 4);
281 if (ret) { 628 if (ret) {
282 kfree(ifbdev); 629 kfree(ifbdev);
283 return ret; 630 return ret;
284 } 631 }
285 632
633 dev_priv->fbdev = ifbdev;
286 drm_fb_helper_single_add_all_connectors(&ifbdev->helper); 634 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
287 635
288 return 0; 636 return 0;
@@ -291,9 +639,10 @@ int intel_fbdev_init(struct drm_device *dev)
291void intel_fbdev_initial_config(struct drm_device *dev) 639void intel_fbdev_initial_config(struct drm_device *dev)
292{ 640{
293 struct drm_i915_private *dev_priv = dev->dev_private; 641 struct drm_i915_private *dev_priv = dev->dev_private;
642 struct intel_fbdev *ifbdev = dev_priv->fbdev;
294 643
295 /* Due to peculiar init order wrt to hpd handling this is separate. */ 644 /* Due to peculiar init order wrt to hpd handling this is separate. */
296 drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); 645 drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp);
297} 646}
298 647
299void intel_fbdev_fini(struct drm_device *dev) 648void intel_fbdev_fini(struct drm_device *dev)
@@ -322,7 +671,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state)
322 * been restored from swap. If the object is stolen however, it will be 671 * been restored from swap. If the object is stolen however, it will be
323 * full of whatever garbage was left in there. 672 * full of whatever garbage was left in there.
324 */ 673 */
325 if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen) 674 if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
326 memset_io(info->screen_base, 0, info->screen_size); 675 memset_io(info->screen_base, 0, info->screen_size);
327 676
328 fb_set_suspend(info, state); 677 fb_set_suspend(info, state);
@@ -331,7 +680,8 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state)
331void intel_fbdev_output_poll_changed(struct drm_device *dev) 680void intel_fbdev_output_poll_changed(struct drm_device *dev)
332{ 681{
333 struct drm_i915_private *dev_priv = dev->dev_private; 682 struct drm_i915_private *dev_priv = dev->dev_private;
334 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); 683 if (dev_priv->fbdev)
684 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
335} 685}
336 686
337void intel_fbdev_restore_mode(struct drm_device *dev) 687void intel_fbdev_restore_mode(struct drm_device *dev)
@@ -339,7 +689,7 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
339 int ret; 689 int ret;
340 struct drm_i915_private *dev_priv = dev->dev_private; 690 struct drm_i915_private *dev_priv = dev->dev_private;
341 691
342 if (INTEL_INFO(dev)->num_pipes == 0) 692 if (!dev_priv->fbdev)
343 return; 693 return;
344 694
345 drm_modeset_lock_all(dev); 695 drm_modeset_lock_all(dev);