Merge branch 'vendor/OPENSSL'
[dragonfly.git] / sys / dev / drm / i915 / intel_fbdev.c
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 <drm/drmP.h>
28 #include <linux/async.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/errno.h>
32 #include <linux/string.h>
33 #include <linux/mm.h>
34 #include <linux/delay.h>
35 #include <linux/fb.h>
36
37 #include <drm/drmP.h>
38 #include <drm/drm_crtc.h>
39 #include <drm/drm_fb_helper.h>
40 #include "intel_drv.h"
41 #include <drm/i915_drm.h>
42 #include "i915_drv.h"
43
44 #if 0
45 static int intel_fbdev_set_par(struct fb_info *info)
46 {
47         struct drm_fb_helper *fb_helper = info->par;
48         struct intel_fbdev *ifbdev =
49                 container_of(fb_helper, struct intel_fbdev, helper);
50         int ret;
51
52         ret = drm_fb_helper_set_par(info);
53
54         if (ret == 0) {
55                 /*
56                  * FIXME: fbdev presumes that all callbacks also work from
57                  * atomic contexts and relies on that for emergency oops
58                  * printing. KMS totally doesn't do that and the locking here is
59                  * by far not the only place this goes wrong.  Ignore this for
60                  * now until we solve this for real.
61                  */
62                 mutex_lock(&fb_helper->dev->struct_mutex);
63                 ret = i915_gem_object_set_to_gtt_domain(ifbdev->fb->obj,
64                                                         true);
65                 mutex_unlock(&fb_helper->dev->struct_mutex);
66         }
67
68         return ret;
69 }
70
71 static int intel_fbdev_blank(int blank, struct fb_info *info)
72 {
73         struct drm_fb_helper *fb_helper = info->par;
74         struct intel_fbdev *ifbdev =
75                 container_of(fb_helper, struct intel_fbdev, helper);
76         int ret;
77
78         ret = drm_fb_helper_blank(blank, info);
79
80         if (ret == 0) {
81                 /*
82                  * FIXME: fbdev presumes that all callbacks also work from
83                  * atomic contexts and relies on that for emergency oops
84                  * printing. KMS totally doesn't do that and the locking here is
85                  * by far not the only place this goes wrong.  Ignore this for
86                  * now until we solve this for real.
87                  */
88                 mutex_lock(&fb_helper->dev->struct_mutex);
89                 intel_fb_obj_invalidate(ifbdev->fb->obj, NULL, ORIGIN_GTT);
90                 mutex_unlock(&fb_helper->dev->struct_mutex);
91         }
92
93         return ret;
94 }
95
96 static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
97                                    struct fb_info *info)
98 {
99         struct drm_fb_helper *fb_helper = info->par;
100         struct intel_fbdev *ifbdev =
101                 container_of(fb_helper, struct intel_fbdev, helper);
102
103         int ret;
104         ret = drm_fb_helper_pan_display(var, info);
105
106         if (ret == 0) {
107                 /*
108                  * FIXME: fbdev presumes that all callbacks also work from
109                  * atomic contexts and relies on that for emergency oops
110                  * printing. KMS totally doesn't do that and the locking here is
111                  * by far not the only place this goes wrong.  Ignore this for
112                  * now until we solve this for real.
113                  */
114                 mutex_lock(&fb_helper->dev->struct_mutex);
115                 intel_fb_obj_invalidate(ifbdev->fb->obj, NULL, ORIGIN_GTT);
116                 mutex_unlock(&fb_helper->dev->struct_mutex);
117         }
118
119         return ret;
120 }
121
122 static struct fb_ops intelfb_ops = {
123         .owner = THIS_MODULE,
124         .fb_check_var = drm_fb_helper_check_var,
125         .fb_set_par = intel_fbdev_set_par,
126         .fb_fillrect = cfb_fillrect,
127         .fb_copyarea = cfb_copyarea,
128         .fb_imageblit = cfb_imageblit,
129         .fb_pan_display = intel_fbdev_pan_display,
130         .fb_blank = intel_fbdev_blank,
131         .fb_setcmap = drm_fb_helper_setcmap,
132         .fb_debug_enter = drm_fb_helper_debug_enter,
133         .fb_debug_leave = drm_fb_helper_debug_leave,
134 };
135 #endif
136
137 static int intelfb_alloc(struct drm_fb_helper *helper,
138                          struct drm_fb_helper_surface_size *sizes)
139 {
140         struct intel_fbdev *ifbdev =
141                 container_of(helper, struct intel_fbdev, helper);
142         struct drm_framebuffer *fb;
143         struct drm_device *dev = helper->dev;
144         struct drm_mode_fb_cmd2 mode_cmd = {};
145         struct drm_i915_gem_object *obj;
146         int size, ret;
147
148         /* we don't do packed 24bpp */
149         if (sizes->surface_bpp == 24)
150                 sizes->surface_bpp = 32;
151
152         mode_cmd.width = sizes->surface_width;
153         mode_cmd.height = sizes->surface_height;
154
155         mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
156                                     DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
157         mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
158                                                           sizes->surface_depth);
159
160         size = mode_cmd.pitches[0] * mode_cmd.height;
161         size = PAGE_ALIGN(size);
162         obj = i915_gem_object_create_stolen(dev, size);
163         if (obj == NULL)
164                 obj = i915_gem_alloc_object(dev, size);
165         if (!obj) {
166                 DRM_ERROR("failed to allocate framebuffer\n");
167                 ret = -ENOMEM;
168                 goto out;
169         }
170
171         fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
172         if (IS_ERR(fb)) {
173                 ret = PTR_ERR(fb);
174                 goto out_unref;
175         }
176
177         /* Flush everything out, we'll be doing GTT only from now on */
178         ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL);
179         if (ret) {
180                 DRM_ERROR("failed to pin obj: %d\n", ret);
181                 goto out_fb;
182         }
183
184         ifbdev->fb = to_intel_framebuffer(fb);
185
186         return 0;
187
188 out_fb:
189         drm_framebuffer_remove(fb);
190 out_unref:
191         drm_gem_object_unreference(&obj->base);
192 out:
193         return ret;
194 }
195
196 static int intelfb_create(struct drm_fb_helper *helper,
197                           struct drm_fb_helper_surface_size *sizes)
198 {
199         struct intel_fbdev *ifbdev =
200                 container_of(helper, struct intel_fbdev, helper);
201         struct intel_framebuffer *intel_fb = ifbdev->fb;
202         struct drm_device *dev = helper->dev;
203         struct drm_i915_private *dev_priv = dev->dev_private;
204         struct fb_info *info;
205         struct drm_framebuffer *fb;
206         struct drm_i915_gem_object *obj;
207         device_t vga_dev;
208         int size, ret;
209         bool prealloc = false;
210
211         mutex_lock(&dev->struct_mutex);
212
213         if (intel_fb &&
214             (sizes->fb_width > intel_fb->base.width ||
215              sizes->fb_height > intel_fb->base.height)) {
216                 DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
217                               " releasing it\n",
218                               intel_fb->base.width, intel_fb->base.height,
219                               sizes->fb_width, sizes->fb_height);
220                 drm_framebuffer_unreference(&intel_fb->base);
221                 intel_fb = ifbdev->fb = NULL;
222         }
223         if (!intel_fb || WARN_ON(!intel_fb->obj)) {
224                 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
225                 ret = intelfb_alloc(helper, sizes);
226                 if (ret)
227                         goto out_unlock;
228                 intel_fb = ifbdev->fb;
229         } else {
230                 DRM_DEBUG_KMS("re-using BIOS fb\n");
231                 prealloc = true;
232                 sizes->fb_width = intel_fb->base.width;
233                 sizes->fb_height = intel_fb->base.height;
234         }
235
236         obj = intel_fb->obj;
237         size = obj->base.size;
238
239 #if 0
240         info = framebuffer_alloc(0, &dev->pdev->dev);
241 #else
242         info = kmalloc(sizeof(struct fb_info), M_DRM, M_WAITOK | M_ZERO);
243 #endif
244         if (!info) {
245                 ret = -ENOMEM;
246                 goto out_unpin;
247         }
248
249 #if 0
250         info->par = helper;
251 #endif
252
253         fb = &ifbdev->fb->base;
254
255 #ifdef __DragonFly__
256         vga_dev = device_get_parent(dev->dev);
257         info->width = sizes->fb_width;
258         info->height = sizes->fb_height;
259         info->stride = fb->pitches[0];
260         info->depth = sizes->surface_bpp;
261         info->paddr = dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj);
262         info->is_vga_boot_display = vga_pci_is_boot_display(vga_dev);
263         info->vaddr =
264             (vm_offset_t)pmap_mapdev_attr(info->paddr,
265                 sizes->surface_height * info->stride,
266                 VM_MEMATTR_WRITE_COMBINING);
267 #endif
268
269         ifbdev->helper.fb = fb;
270         ifbdev->helper.fbdev = info;
271
272 #if 0
273         strcpy(info->fix.id, "inteldrmfb");
274
275         info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
276         info->fbops = &intelfb_ops;
277
278         ret = fb_alloc_cmap(&info->cmap, 256, 0);
279         if (ret) {
280                 ret = -ENOMEM;
281                 goto out_unpin;
282         }
283         /* setup aperture base/size for vesafb takeover */
284         info->apertures = alloc_apertures(1);
285         if (!info->apertures) {
286                 ret = -ENOMEM;
287                 goto out_unpin;
288         }
289         info->apertures->ranges[0].base = dev->mode_config.fb_base;
290         info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
291
292         info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
293         info->fix.smem_len = size;
294
295         info->screen_base =
296                 ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
297                            size);
298         if (!info->screen_base) {
299                 ret = -ENOSPC;
300                 goto out_unpin;
301         }
302         info->screen_size = size;
303
304         /* This driver doesn't need a VT switch to restore the mode on resume */
305         info->skip_vt_switch = true;
306
307         drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
308         drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
309
310         /* If the object is shmemfs backed, it will have given us zeroed pages.
311          * If the object is stolen however, it will be full of whatever
312          * garbage was left in there.
313          */
314         if (ifbdev->fb->obj->stolen && !prealloc)
315                 memset_io(info->screen_base, 0, info->screen_size);
316
317         /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
318 #endif
319
320         DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
321                       fb->width, fb->height,
322                       i915_gem_obj_ggtt_offset(obj), obj);
323
324         mutex_unlock(&dev->struct_mutex);
325 #if 0
326         vga_switcheroo_client_fb_set(dev->pdev, info);
327 #endif
328         return 0;
329
330 out_unpin:
331         i915_gem_object_ggtt_unpin(obj);
332         drm_gem_object_unreference(&obj->base);
333 out_unlock:
334         mutex_unlock(&dev->struct_mutex);
335         return ret;
336 }
337
338 /** Sets the color ramps on behalf of RandR */
339 static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
340                                     u16 blue, int regno)
341 {
342         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
343
344         intel_crtc->lut_r[regno] = red >> 8;
345         intel_crtc->lut_g[regno] = green >> 8;
346         intel_crtc->lut_b[regno] = blue >> 8;
347 }
348
349 static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
350                                     u16 *blue, int regno)
351 {
352         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
353
354         *red = intel_crtc->lut_r[regno] << 8;
355         *green = intel_crtc->lut_g[regno] << 8;
356         *blue = intel_crtc->lut_b[regno] << 8;
357 }
358
359 static struct drm_fb_helper_crtc *
360 intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
361 {
362         int i;
363
364         for (i = 0; i < fb_helper->crtc_count; i++)
365                 if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
366                         return &fb_helper->crtc_info[i];
367
368         return NULL;
369 }
370
371 /*
372  * Try to read the BIOS display configuration and use it for the initial
373  * fb configuration.
374  *
375  * The BIOS or boot loader will generally create an initial display
376  * configuration for us that includes some set of active pipes and displays.
377  * This routine tries to figure out which pipes and connectors are active
378  * and stuffs them into the crtcs and modes array given to us by the
379  * drm_fb_helper code.
380  *
381  * The overall sequence is:
382  *   intel_fbdev_init - from driver load
383  *     intel_fbdev_init_bios - initialize the intel_fbdev using BIOS data
384  *     drm_fb_helper_init - build fb helper structs
385  *     drm_fb_helper_single_add_all_connectors - more fb helper structs
386  *   intel_fbdev_initial_config - apply the config
387  *     drm_fb_helper_initial_config - call ->probe then register_framebuffer()
388  *         drm_setup_crtcs - build crtc config for fbdev
389  *           intel_fb_initial_config - find active connectors etc
390  *         drm_fb_helper_single_fb_probe - set up fbdev
391  *           intelfb_create - re-use or alloc fb, build out fbdev structs
392  *
393  * Note that we don't make special consideration whether we could actually
394  * switch to the selected modes without a full modeset. E.g. when the display
395  * is in VGA mode we need to recalculate watermarks and set a new high-res
396  * framebuffer anyway.
397  */
398 static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
399                                     struct drm_fb_helper_crtc **crtcs,
400                                     struct drm_display_mode **modes,
401                                     struct drm_fb_offset *offsets,
402                                     bool *enabled, int width, int height)
403 {
404         struct drm_device *dev = fb_helper->dev;
405         int i, j;
406         bool *save_enabled;
407         bool fallback = true;
408         int num_connectors_enabled = 0;
409         int num_connectors_detected = 0;
410         uint64_t conn_configured = 0, mask;
411         int pass = 0;
412
413         save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
414                                GFP_KERNEL);
415         if (!save_enabled)
416                 return false;
417
418         memcpy(save_enabled, enabled, dev->mode_config.num_connector);
419         mask = (1 << fb_helper->connector_count) - 1;
420 retry:
421         for (i = 0; i < fb_helper->connector_count; i++) {
422                 struct drm_fb_helper_connector *fb_conn;
423                 struct drm_connector *connector;
424                 struct drm_encoder *encoder;
425                 struct drm_fb_helper_crtc *new_crtc;
426
427                 fb_conn = fb_helper->connector_info[i];
428                 connector = fb_conn->connector;
429
430                 if (conn_configured & (1 << i))
431                         continue;
432
433                 if (pass == 0 && !connector->has_tile)
434                         continue;
435
436                 if (connector->status == connector_status_connected)
437                         num_connectors_detected++;
438
439                 if (!enabled[i]) {
440                         DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
441                                       connector->name);
442                         conn_configured |= (1 << i);
443                         continue;
444                 }
445
446                 if (connector->force == DRM_FORCE_OFF) {
447                         DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
448                                       connector->name);
449                         enabled[i] = false;
450                         continue;
451                 }
452
453                 encoder = connector->encoder;
454                 if (!encoder || WARN_ON(!encoder->crtc)) {
455                         if (connector->force > DRM_FORCE_OFF)
456                                 goto bail;
457
458                         DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
459                                       connector->name);
460                         enabled[i] = false;
461                         conn_configured |= (1 << i);
462                         continue;
463                 }
464
465                 num_connectors_enabled++;
466
467                 new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc);
468
469                 /*
470                  * Make sure we're not trying to drive multiple connectors
471                  * with a single CRTC, since our cloning support may not
472                  * match the BIOS.
473                  */
474                 for (j = 0; j < fb_helper->connector_count; j++) {
475                         if (crtcs[j] == new_crtc) {
476                                 DRM_DEBUG_KMS("fallback: cloned configuration\n");
477                                 goto bail;
478                         }
479                 }
480
481                 DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
482                               connector->name);
483
484                 /* go for command line mode first */
485                 modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
486
487                 /* try for preferred next */
488                 if (!modes[i]) {
489                         DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
490                                       connector->name, connector->has_tile);
491                         modes[i] = drm_has_preferred_mode(fb_conn, width,
492                                                           height);
493                 }
494
495                 /* No preferred mode marked by the EDID? Are there any modes? */
496                 if (!modes[i] && !list_empty(&connector->modes)) {
497                         DRM_DEBUG_KMS("using first mode listed on connector %s\n",
498                                       connector->name);
499                         modes[i] = list_first_entry(&connector->modes,
500                                                     struct drm_display_mode,
501                                                     head);
502                 }
503
504                 /* last resort: use current mode */
505                 if (!modes[i]) {
506                         /*
507                          * IMPORTANT: We want to use the adjusted mode (i.e.
508                          * after the panel fitter upscaling) as the initial
509                          * config, not the input mode, which is what crtc->mode
510                          * usually contains. But since our current fastboot
511                          * code puts a mode derived from the post-pfit timings
512                          * into crtc->mode this works out correctly. We don't
513                          * use hwmode anywhere right now, so use it for this
514                          * since the fb helper layer wants a pointer to
515                          * something we own.
516                          */
517                         DRM_DEBUG_KMS("looking for current mode on connector %s\n",
518                                       connector->name);
519                         intel_mode_from_pipe_config(&encoder->crtc->hwmode,
520                                                     to_intel_crtc(encoder->crtc)->config);
521                         modes[i] = &encoder->crtc->hwmode;
522                 }
523                 crtcs[i] = new_crtc;
524
525                 DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
526                               connector->name,
527                               pipe_name(to_intel_crtc(encoder->crtc)->pipe),
528                               encoder->crtc->base.id,
529                               modes[i]->hdisplay, modes[i]->vdisplay,
530                               modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
531
532                 fallback = false;
533                 conn_configured |= (1 << i);
534         }
535
536         if ((conn_configured & mask) != mask) {
537                 pass++;
538                 goto retry;
539         }
540
541         /*
542          * If the BIOS didn't enable everything it could, fall back to have the
543          * same user experiencing of lighting up as much as possible like the
544          * fbdev helper library.
545          */
546         if (num_connectors_enabled != num_connectors_detected &&
547             num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
548                 DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
549                 DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
550                               num_connectors_detected);
551                 fallback = true;
552         }
553
554         if (fallback) {
555 bail:
556                 DRM_DEBUG_KMS("Not using firmware configuration\n");
557                 memcpy(enabled, save_enabled, dev->mode_config.num_connector);
558                 kfree(save_enabled);
559                 return false;
560         }
561
562         kfree(save_enabled);
563         return true;
564 }
565
566 static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
567         .initial_config = intel_fb_initial_config,
568         .gamma_set = intel_crtc_fb_gamma_set,
569         .gamma_get = intel_crtc_fb_gamma_get,
570         .fb_probe = intelfb_create,
571 };
572
573 static void intel_fbdev_destroy(struct drm_device *dev,
574                                 struct intel_fbdev *ifbdev)
575 {
576 #if 0
577         if (ifbdev->helper.fbdev) {
578                 struct fb_info *info = ifbdev->helper.fbdev;
579
580                 unregister_framebuffer(info);
581                 iounmap(info->screen_base);
582                 if (info->cmap.len)
583                         fb_dealloc_cmap(&info->cmap);
584
585                 framebuffer_release(info);
586         }
587 #endif
588
589         drm_fb_helper_fini(&ifbdev->helper);
590
591         drm_framebuffer_unregister_private(&ifbdev->fb->base);
592         drm_framebuffer_remove(&ifbdev->fb->base);
593 }
594
595 /*
596  * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
597  * The core display code will have read out the current plane configuration,
598  * so we use that to figure out if there's an object for us to use as the
599  * fb, and if so, we re-use it for the fbdev configuration.
600  *
601  * Note we only support a single fb shared across pipes for boot (mostly for
602  * fbcon), so we just find the biggest and use that.
603  */
604 static bool intel_fbdev_init_bios(struct drm_device *dev,
605                                  struct intel_fbdev *ifbdev)
606 {
607         struct intel_framebuffer *fb = NULL;
608         struct drm_crtc *crtc;
609         struct intel_crtc *intel_crtc;
610         struct intel_initial_plane_config *plane_config = NULL;
611         unsigned int max_size = 0;
612
613         if (!i915.fastboot)
614                 return false;
615
616         /* Find the largest fb */
617         for_each_crtc(dev, crtc) {
618                 intel_crtc = to_intel_crtc(crtc);
619
620                 if (!intel_crtc->active || !crtc->primary->fb) {
621                         DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
622                                       pipe_name(intel_crtc->pipe));
623                         continue;
624                 }
625
626                 if (intel_crtc->plane_config.size > max_size) {
627                         DRM_DEBUG_KMS("found possible fb from plane %c\n",
628                                       pipe_name(intel_crtc->pipe));
629                         plane_config = &intel_crtc->plane_config;
630                         fb = to_intel_framebuffer(crtc->primary->fb);
631                         max_size = plane_config->size;
632                 }
633         }
634
635         if (!fb) {
636                 DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
637                 goto out;
638         }
639
640         /* Now make sure all the pipes will fit into it */
641         for_each_crtc(dev, crtc) {
642                 unsigned int cur_size;
643
644                 intel_crtc = to_intel_crtc(crtc);
645
646                 if (!intel_crtc->active) {
647                         DRM_DEBUG_KMS("pipe %c not active, skipping\n",
648                                       pipe_name(intel_crtc->pipe));
649                         continue;
650                 }
651
652                 DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
653                               pipe_name(intel_crtc->pipe));
654
655                 /*
656                  * See if the plane fb we found above will fit on this
657                  * pipe.  Note we need to use the selected fb's pitch and bpp
658                  * rather than the current pipe's, since they differ.
659                  */
660                 cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
661                 cur_size = cur_size * fb->base.bits_per_pixel / 8;
662                 if (fb->base.pitches[0] < cur_size) {
663                         DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
664                                       pipe_name(intel_crtc->pipe),
665                                       cur_size, fb->base.pitches[0]);
666                         plane_config = NULL;
667                         fb = NULL;
668                         break;
669                 }
670
671                 cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
672                 cur_size = intel_fb_align_height(dev, cur_size,
673                                                  fb->base.pixel_format,
674                                                  fb->base.modifier[0]);
675                 cur_size *= fb->base.pitches[0];
676                 DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
677                               pipe_name(intel_crtc->pipe),
678                               intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
679                               intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
680                               fb->base.bits_per_pixel,
681                               cur_size);
682
683                 if (cur_size > max_size) {
684                         DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
685                                       pipe_name(intel_crtc->pipe),
686                                       cur_size, max_size);
687                         plane_config = NULL;
688                         fb = NULL;
689                         break;
690                 }
691
692                 DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
693                               pipe_name(intel_crtc->pipe),
694                               max_size, cur_size);
695         }
696
697         if (!fb) {
698                 DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
699                 goto out;
700         }
701
702         ifbdev->preferred_bpp = fb->base.bits_per_pixel;
703         ifbdev->fb = fb;
704
705         drm_framebuffer_reference(&ifbdev->fb->base);
706
707         /* Final pass to check if any active pipes don't have fbs */
708         for_each_crtc(dev, crtc) {
709                 intel_crtc = to_intel_crtc(crtc);
710
711                 if (!intel_crtc->active)
712                         continue;
713
714                 WARN(!crtc->primary->fb,
715                      "re-used BIOS config but lost an fb on crtc %d\n",
716                      crtc->base.id);
717         }
718
719
720         DRM_DEBUG_KMS("using BIOS fb for initial console\n");
721         return true;
722
723 out:
724
725         return false;
726 }
727
728 static void intel_fbdev_suspend_worker(struct work_struct *work)
729 {
730         intel_fbdev_set_suspend(container_of(work,
731                                              struct drm_i915_private,
732                                              fbdev_suspend_work)->dev,
733                                 FBINFO_STATE_RUNNING,
734                                 true);
735 }
736
737 int intel_fbdev_init(struct drm_device *dev)
738 {
739         struct intel_fbdev *ifbdev;
740         struct drm_i915_private *dev_priv = dev->dev_private;
741         int ret;
742
743         if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
744                 return -ENODEV;
745
746         ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
747         if (ifbdev == NULL)
748                 return -ENOMEM;
749
750         drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
751
752         if (!intel_fbdev_init_bios(dev, ifbdev))
753                 ifbdev->preferred_bpp = 32;
754
755         ret = drm_fb_helper_init(dev, &ifbdev->helper,
756                                  INTEL_INFO(dev)->num_pipes, 4);
757         if (ret) {
758                 kfree(ifbdev);
759                 return ret;
760         }
761
762         dev_priv->fbdev = ifbdev;
763         INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
764
765         drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
766
767         return 0;
768 }
769
770 void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
771 {
772         struct drm_i915_private *dev_priv = data;
773         struct intel_fbdev *ifbdev = dev_priv->fbdev;
774
775         /* Due to peculiar init order wrt to hpd handling this is separate. */
776         drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp);
777 }
778
779 void intel_fbdev_fini(struct drm_device *dev)
780 {
781         struct drm_i915_private *dev_priv = dev->dev_private;
782         if (!dev_priv->fbdev)
783                 return;
784
785 #if 0
786         flush_work(&dev_priv->fbdev_suspend_work);
787 #endif
788
789         async_synchronize_full();
790         intel_fbdev_destroy(dev, dev_priv->fbdev);
791         kfree(dev_priv->fbdev);
792         dev_priv->fbdev = NULL;
793 }
794
795 void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
796 {
797 #if 0
798         struct drm_i915_private *dev_priv = dev->dev_private;
799         struct intel_fbdev *ifbdev = dev_priv->fbdev;
800         struct fb_info *info;
801
802         if (!ifbdev)
803                 return;
804
805         info = ifbdev->helper.fbdev;
806
807         if (synchronous) {
808                 /* Flush any pending work to turn the console on, and then
809                  * wait to turn it off. It must be synchronous as we are
810                  * about to suspend or unload the driver.
811                  *
812                  * Note that from within the work-handler, we cannot flush
813                  * ourselves, so only flush outstanding work upon suspend!
814                  */
815                 if (state != FBINFO_STATE_RUNNING)
816                         flush_work(&dev_priv->fbdev_suspend_work);
817                 console_lock();
818         } else {
819                 /*
820                  * The console lock can be pretty contented on resume due
821                  * to all the printk activity.  Try to keep it out of the hot
822                  * path of resume if possible.
823                  */
824                 WARN_ON(state != FBINFO_STATE_RUNNING);
825                 if (!console_trylock()) {
826                         /* Don't block our own workqueue as this can
827                          * be run in parallel with other i915.ko tasks.
828                          */
829                         schedule_work(&dev_priv->fbdev_suspend_work);
830                         return;
831                 }
832         }
833
834         /* On resume from hibernation: If the object is shmemfs backed, it has
835          * been restored from swap. If the object is stolen however, it will be
836          * full of whatever garbage was left in there.
837          */
838         if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
839                 memset_io(info->screen_base, 0, info->screen_size);
840
841         fb_set_suspend(info, state);
842         console_unlock();
843 #endif
844 }
845
846 void intel_fbdev_output_poll_changed(struct drm_device *dev)
847 {
848         struct drm_i915_private *dev_priv = dev->dev_private;
849         if (dev_priv->fbdev)
850                 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
851 }
852
853 void intel_fbdev_restore_mode(struct drm_device *dev)
854 {
855         int ret;
856         struct drm_i915_private *dev_priv = dev->dev_private;
857
858         if (!dev_priv->fbdev)
859                 return;
860
861         ret = drm_fb_helper_restore_fbdev_mode_unlocked(&dev_priv->fbdev->helper);
862         if (ret)
863                 DRM_DEBUG("failed to restore crtc mode\n");
864 }