1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/async.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/console.h>
31#include <linux/errno.h>
32#include <linux/string.h>
33#include <linux/mm.h>
34#include <linux/tty.h>
35#include <linux/sysrq.h>
36#include <linux/delay.h>
37#include <linux/fb.h>
38#include <linux/init.h>
39#include <linux/vga_switcheroo.h>
40
41#include <drm/drmP.h>
42#include <drm/drm_crtc.h>
43#include <drm/drm_fb_helper.h>
44#include "intel_drv.h"
45#include <drm/i915_drm.h>
46#include "i915_drv.h"
47
48static int intel_fbdev_set_par(struct fb_info *info)
49{
50 struct drm_fb_helper *fb_helper = info->par;
51 struct intel_fbdev *ifbdev =
52 container_of(fb_helper, struct intel_fbdev, helper);
53 int ret;
54
55 ret = drm_fb_helper_set_par(info);
56
57 if (ret == 0) {
58
59
60
61
62
63
64
65 mutex_lock(&fb_helper->dev->struct_mutex);
66 ret = i915_gem_object_set_to_gtt_domain(ifbdev->fb->obj,
67 true);
68 mutex_unlock(&fb_helper->dev->struct_mutex);
69 }
70
71 return ret;
72}
73
74static int intel_fbdev_blank(int blank, struct fb_info *info)
75{
76 struct drm_fb_helper *fb_helper = info->par;
77 struct intel_fbdev *ifbdev =
78 container_of(fb_helper, struct intel_fbdev, helper);
79 int ret;
80
81 ret = drm_fb_helper_blank(blank, info);
82
83 if (ret == 0) {
84
85
86
87
88
89
90
91 mutex_lock(&fb_helper->dev->struct_mutex);
92 intel_fb_obj_invalidate(ifbdev->fb->obj, NULL, ORIGIN_GTT);
93 mutex_unlock(&fb_helper->dev->struct_mutex);
94 }
95
96 return ret;
97}
98
99static struct fb_ops intelfb_ops = {
100 .owner = THIS_MODULE,
101 .fb_check_var = drm_fb_helper_check_var,
102 .fb_set_par = intel_fbdev_set_par,
103 .fb_fillrect = cfb_fillrect,
104 .fb_copyarea = cfb_copyarea,
105 .fb_imageblit = cfb_imageblit,
106 .fb_pan_display = drm_fb_helper_pan_display,
107 .fb_blank = intel_fbdev_blank,
108 .fb_setcmap = drm_fb_helper_setcmap,
109 .fb_debug_enter = drm_fb_helper_debug_enter,
110 .fb_debug_leave = drm_fb_helper_debug_leave,
111};
112
113static int intelfb_alloc(struct drm_fb_helper *helper,
114 struct drm_fb_helper_surface_size *sizes)
115{
116 struct intel_fbdev *ifbdev =
117 container_of(helper, struct intel_fbdev, helper);
118 struct drm_framebuffer *fb;
119 struct drm_device *dev = helper->dev;
120 struct drm_mode_fb_cmd2 mode_cmd = {};
121 struct drm_i915_gem_object *obj;
122 int size, ret;
123
124
125 if (sizes->surface_bpp == 24)
126 sizes->surface_bpp = 32;
127
128 mode_cmd.width = sizes->surface_width;
129 mode_cmd.height = sizes->surface_height;
130
131 mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
132 DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
133 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
134 sizes->surface_depth);
135
136 size = mode_cmd.pitches[0] * mode_cmd.height;
137 size = PAGE_ALIGN(size);
138 obj = i915_gem_object_create_stolen(dev, size);
139 if (obj == NULL)
140 obj = i915_gem_alloc_object(dev, size);
141 if (!obj) {
142 DRM_ERROR("failed to allocate framebuffer\n");
143 ret = -ENOMEM;
144 goto out;
145 }
146
147 fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
148 if (IS_ERR(fb)) {
149 ret = PTR_ERR(fb);
150 goto out_unref;
151 }
152
153
154 ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL);
155 if (ret) {
156 DRM_ERROR("failed to pin obj: %d\n", ret);
157 goto out_fb;
158 }
159
160 ifbdev->fb = to_intel_framebuffer(fb);
161
162 return 0;
163
164out_fb:
165 drm_framebuffer_remove(fb);
166out_unref:
167 drm_gem_object_unreference(&obj->base);
168out:
169 return ret;
170}
171
172static int intelfb_create(struct drm_fb_helper *helper,
173 struct drm_fb_helper_surface_size *sizes)
174{
175 struct intel_fbdev *ifbdev =
176 container_of(helper, struct intel_fbdev, helper);
177 struct intel_framebuffer *intel_fb = ifbdev->fb;
178 struct drm_device *dev = helper->dev;
179 struct drm_i915_private *dev_priv = dev->dev_private;
180 struct fb_info *info;
181 struct drm_framebuffer *fb;
182 struct drm_i915_gem_object *obj;
183 int size, ret;
184 bool prealloc = false;
185
186 mutex_lock(&dev->struct_mutex);
187
188 if (intel_fb &&
189 (sizes->fb_width > intel_fb->base.width ||
190 sizes->fb_height > intel_fb->base.height)) {
191 DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
192 " releasing it\n",
193 intel_fb->base.width, intel_fb->base.height,
194 sizes->fb_width, sizes->fb_height);
195 drm_framebuffer_unreference(&intel_fb->base);
196 intel_fb = ifbdev->fb = NULL;
197 }
198 if (!intel_fb || WARN_ON(!intel_fb->obj)) {
199 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
200 ret = intelfb_alloc(helper, sizes);
201 if (ret)
202 goto out_unlock;
203 intel_fb = ifbdev->fb;
204 } else {
205 DRM_DEBUG_KMS("re-using BIOS fb\n");
206 prealloc = true;
207 sizes->fb_width = intel_fb->base.width;
208 sizes->fb_height = intel_fb->base.height;
209 }
210
211 obj = intel_fb->obj;
212 size = obj->base.size;
213
214 info = framebuffer_alloc(0, &dev->pdev->dev);
215 if (!info) {
216 ret = -ENOMEM;
217 goto out_unpin;
218 }
219
220 info->par = helper;
221
222 fb = &ifbdev->fb->base;
223
224 ifbdev->helper.fb = fb;
225 ifbdev->helper.fbdev = info;
226
227 strcpy(info->fix.id, "inteldrmfb");
228
229 info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
230 info->fbops = &intelfb_ops;
231
232 ret = fb_alloc_cmap(&info->cmap, 256, 0);
233 if (ret) {
234 ret = -ENOMEM;
235 goto out_unpin;
236 }
237
238 info->apertures = alloc_apertures(1);
239 if (!info->apertures) {
240 ret = -ENOMEM;
241 goto out_unpin;
242 }
243 info->apertures->ranges[0].base = dev->mode_config.fb_base;
244 info->apertures->ranges[0].size = dev_priv->gtt.mappable_end;
245
246 info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
247 info->fix.smem_len = size;
248
249 info->screen_base =
250 ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
251 size);
252 if (!info->screen_base) {
253 ret = -ENOSPC;
254 goto out_unpin;
255 }
256 info->screen_size = size;
257
258
259 info->skip_vt_switch = true;
260
261 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
262 drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
263
264
265
266
267
268 if (ifbdev->fb->obj->stolen && !prealloc)
269 memset_io(info->screen_base, 0, info->screen_size);
270
271
272
273 DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
274 fb->width, fb->height,
275 i915_gem_obj_ggtt_offset(obj), obj);
276
277 mutex_unlock(&dev->struct_mutex);
278 vga_switcheroo_client_fb_set(dev->pdev, info);
279 return 0;
280
281out_unpin:
282 i915_gem_object_ggtt_unpin(obj);
283 drm_gem_object_unreference(&obj->base);
284out_unlock:
285 mutex_unlock(&dev->struct_mutex);
286 return ret;
287}
288
289
290static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
291 u16 blue, int regno)
292{
293 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
294
295 intel_crtc->lut_r[regno] = red >> 8;
296 intel_crtc->lut_g[regno] = green >> 8;
297 intel_crtc->lut_b[regno] = blue >> 8;
298}
299
300static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
301 u16 *blue, int regno)
302{
303 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
304
305 *red = intel_crtc->lut_r[regno] << 8;
306 *green = intel_crtc->lut_g[regno] << 8;
307 *blue = intel_crtc->lut_b[regno] << 8;
308}
309
310static struct drm_fb_helper_crtc *
311intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
312{
313 int i;
314
315 for (i = 0; i < fb_helper->crtc_count; i++)
316 if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
317 return &fb_helper->crtc_info[i];
318
319 return NULL;
320}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
350 struct drm_fb_helper_crtc **crtcs,
351 struct drm_display_mode **modes,
352 struct drm_fb_offset *offsets,
353 bool *enabled, int width, int height)
354{
355 struct drm_device *dev = fb_helper->dev;
356 int i, j;
357 bool *save_enabled;
358 bool fallback = true;
359 int num_connectors_enabled = 0;
360 int num_connectors_detected = 0;
361 uint64_t conn_configured = 0, mask;
362 int pass = 0;
363
364 save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
365 GFP_KERNEL);
366 if (!save_enabled)
367 return false;
368
369 memcpy(save_enabled, enabled, dev->mode_config.num_connector);
370 mask = (1 << fb_helper->connector_count) - 1;
371retry:
372 for (i = 0; i < fb_helper->connector_count; i++) {
373 struct drm_fb_helper_connector *fb_conn;
374 struct drm_connector *connector;
375 struct drm_encoder *encoder;
376 struct drm_fb_helper_crtc *new_crtc;
377
378 fb_conn = fb_helper->connector_info[i];
379 connector = fb_conn->connector;
380
381 if (conn_configured & (1 << i))
382 continue;
383
384 if (pass == 0 && !connector->has_tile)
385 continue;
386
387 if (connector->status == connector_status_connected)
388 num_connectors_detected++;
389
390 if (!enabled[i]) {
391 DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
392 connector->name);
393 conn_configured |= (1 << i);
394 continue;
395 }
396
397 if (connector->force == DRM_FORCE_OFF) {
398 DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
399 connector->name);
400 enabled[i] = false;
401 continue;
402 }
403
404 encoder = connector->encoder;
405 if (!encoder || WARN_ON(!encoder->crtc)) {
406 if (connector->force > DRM_FORCE_OFF)
407 goto bail;
408
409 DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
410 connector->name);
411 enabled[i] = false;
412 conn_configured |= (1 << i);
413 continue;
414 }
415
416 num_connectors_enabled++;
417
418 new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc);
419
420
421
422
423
424
425 for (j = 0; j < fb_helper->connector_count; j++) {
426 if (crtcs[j] == new_crtc) {
427 DRM_DEBUG_KMS("fallback: cloned configuration\n");
428 goto bail;
429 }
430 }
431
432 DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
433 connector->name);
434
435
436 modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);
437
438
439 if (!modes[i]) {
440 DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
441 connector->name, connector->has_tile);
442 modes[i] = drm_has_preferred_mode(fb_conn, width,
443 height);
444 }
445
446
447 if (!modes[i] && !list_empty(&connector->modes)) {
448 DRM_DEBUG_KMS("using first mode listed on connector %s\n",
449 connector->name);
450 modes[i] = list_first_entry(&connector->modes,
451 struct drm_display_mode,
452 head);
453 }
454
455
456 if (!modes[i]) {
457
458
459
460
461
462
463
464
465
466
467
468 DRM_DEBUG_KMS("looking for current mode on connector %s\n",
469 connector->name);
470 intel_mode_from_pipe_config(&encoder->crtc->hwmode,
471 to_intel_crtc(encoder->crtc)->config);
472 modes[i] = &encoder->crtc->hwmode;
473 }
474 crtcs[i] = new_crtc;
475
476 DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
477 connector->name,
478 pipe_name(to_intel_crtc(encoder->crtc)->pipe),
479 encoder->crtc->base.id,
480 modes[i]->hdisplay, modes[i]->vdisplay,
481 modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
482
483 fallback = false;
484 conn_configured |= (1 << i);
485 }
486
487 if ((conn_configured & mask) != mask) {
488 pass++;
489 goto retry;
490 }
491
492
493
494
495
496
497 if (num_connectors_enabled != num_connectors_detected &&
498 num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
499 DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
500 DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
501 num_connectors_detected);
502 fallback = true;
503 }
504
505 if (fallback) {
506bail:
507 DRM_DEBUG_KMS("Not using firmware configuration\n");
508 memcpy(enabled, save_enabled, dev->mode_config.num_connector);
509 kfree(save_enabled);
510 return false;
511 }
512
513 kfree(save_enabled);
514 return true;
515}
516
517static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
518 .initial_config = intel_fb_initial_config,
519 .gamma_set = intel_crtc_fb_gamma_set,
520 .gamma_get = intel_crtc_fb_gamma_get,
521 .fb_probe = intelfb_create,
522};
523
524static void intel_fbdev_destroy(struct drm_device *dev,
525 struct intel_fbdev *ifbdev)
526{
527 if (ifbdev->helper.fbdev) {
528 struct fb_info *info = ifbdev->helper.fbdev;
529
530 unregister_framebuffer(info);
531 iounmap(info->screen_base);
532 if (info->cmap.len)
533 fb_dealloc_cmap(&info->cmap);
534
535 framebuffer_release(info);
536 }
537
538 drm_fb_helper_fini(&ifbdev->helper);
539
540 drm_framebuffer_unregister_private(&ifbdev->fb->base);
541 drm_framebuffer_remove(&ifbdev->fb->base);
542}
543
544
545
546
547
548
549
550
551
552
553static bool intel_fbdev_init_bios(struct drm_device *dev,
554 struct intel_fbdev *ifbdev)
555{
556 struct intel_framebuffer *fb = NULL;
557 struct drm_crtc *crtc;
558 struct intel_crtc *intel_crtc;
559 struct intel_initial_plane_config *plane_config = NULL;
560 unsigned int max_size = 0;
561
562 if (!i915.fastboot)
563 return false;
564
565
566 for_each_crtc(dev, crtc) {
567 intel_crtc = to_intel_crtc(crtc);
568
569 if (!intel_crtc->active || !crtc->primary->fb) {
570 DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
571 pipe_name(intel_crtc->pipe));
572 continue;
573 }
574
575 if (intel_crtc->plane_config.size > max_size) {
576 DRM_DEBUG_KMS("found possible fb from plane %c\n",
577 pipe_name(intel_crtc->pipe));
578 plane_config = &intel_crtc->plane_config;
579 fb = to_intel_framebuffer(crtc->primary->fb);
580 max_size = plane_config->size;
581 }
582 }
583
584 if (!fb) {
585 DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
586 goto out;
587 }
588
589
590 for_each_crtc(dev, crtc) {
591 unsigned int cur_size;
592
593 intel_crtc = to_intel_crtc(crtc);
594
595 if (!intel_crtc->active) {
596 DRM_DEBUG_KMS("pipe %c not active, skipping\n",
597 pipe_name(intel_crtc->pipe));
598 continue;
599 }
600
601 DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
602 pipe_name(intel_crtc->pipe));
603
604
605
606
607
608
609 cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
610 cur_size = cur_size * fb->base.bits_per_pixel / 8;
611 if (fb->base.pitches[0] < cur_size) {
612 DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
613 pipe_name(intel_crtc->pipe),
614 cur_size, fb->base.pitches[0]);
615 plane_config = NULL;
616 fb = NULL;
617 break;
618 }
619
620 cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
621 cur_size = intel_fb_align_height(dev, cur_size,
622 fb->base.pixel_format,
623 fb->base.modifier[0]);
624 cur_size *= fb->base.pitches[0];
625 DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
626 pipe_name(intel_crtc->pipe),
627 intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
628 intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
629 fb->base.bits_per_pixel,
630 cur_size);
631
632 if (cur_size > max_size) {
633 DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
634 pipe_name(intel_crtc->pipe),
635 cur_size, max_size);
636 plane_config = NULL;
637 fb = NULL;
638 break;
639 }
640
641 DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
642 pipe_name(intel_crtc->pipe),
643 max_size, cur_size);
644 }
645
646 if (!fb) {
647 DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
648 goto out;
649 }
650
651 ifbdev->preferred_bpp = fb->base.bits_per_pixel;
652 ifbdev->fb = fb;
653
654 drm_framebuffer_reference(&ifbdev->fb->base);
655
656
657 for_each_crtc(dev, crtc) {
658 intel_crtc = to_intel_crtc(crtc);
659
660 if (!intel_crtc->active)
661 continue;
662
663 WARN(!crtc->primary->fb,
664 "re-used BIOS config but lost an fb on crtc %d\n",
665 crtc->base.id);
666 }
667
668
669 DRM_DEBUG_KMS("using BIOS fb for initial console\n");
670 return true;
671
672out:
673
674 return false;
675}
676
677static void intel_fbdev_suspend_worker(struct work_struct *work)
678{
679 intel_fbdev_set_suspend(container_of(work,
680 struct drm_i915_private,
681 fbdev_suspend_work)->dev,
682 FBINFO_STATE_RUNNING,
683 true);
684}
685
686int intel_fbdev_init(struct drm_device *dev)
687{
688 struct intel_fbdev *ifbdev;
689 struct drm_i915_private *dev_priv = dev->dev_private;
690 int ret;
691
692 if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
693 return -ENODEV;
694
695 ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
696 if (ifbdev == NULL)
697 return -ENOMEM;
698
699 drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
700
701 if (!intel_fbdev_init_bios(dev, ifbdev))
702 ifbdev->preferred_bpp = 32;
703
704 ret = drm_fb_helper_init(dev, &ifbdev->helper,
705 INTEL_INFO(dev)->num_pipes, 4);
706 if (ret) {
707 kfree(ifbdev);
708 return ret;
709 }
710
711 dev_priv->fbdev = ifbdev;
712 INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
713
714 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
715
716 return 0;
717}
718
719void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
720{
721 struct drm_i915_private *dev_priv = data;
722 struct intel_fbdev *ifbdev = dev_priv->fbdev;
723
724
725 drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp);
726}
727
728void intel_fbdev_fini(struct drm_device *dev)
729{
730 struct drm_i915_private *dev_priv = dev->dev_private;
731 if (!dev_priv->fbdev)
732 return;
733
734 flush_work(&dev_priv->fbdev_suspend_work);
735
736 async_synchronize_full();
737 intel_fbdev_destroy(dev, dev_priv->fbdev);
738 kfree(dev_priv->fbdev);
739 dev_priv->fbdev = NULL;
740}
741
742void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
743{
744 struct drm_i915_private *dev_priv = dev->dev_private;
745 struct intel_fbdev *ifbdev = dev_priv->fbdev;
746 struct fb_info *info;
747
748 if (!ifbdev)
749 return;
750
751 info = ifbdev->helper.fbdev;
752
753 if (synchronous) {
754
755
756
757
758
759
760
761 if (state != FBINFO_STATE_RUNNING)
762 flush_work(&dev_priv->fbdev_suspend_work);
763 console_lock();
764 } else {
765
766
767
768
769
770 WARN_ON(state != FBINFO_STATE_RUNNING);
771 if (!console_trylock()) {
772
773
774
775 schedule_work(&dev_priv->fbdev_suspend_work);
776 return;
777 }
778 }
779
780
781
782
783
784 if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
785 memset_io(info->screen_base, 0, info->screen_size);
786
787 fb_set_suspend(info, state);
788 console_unlock();
789}
790
791void intel_fbdev_output_poll_changed(struct drm_device *dev)
792{
793 struct drm_i915_private *dev_priv = dev->dev_private;
794 if (dev_priv->fbdev)
795 drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
796}
797
798void intel_fbdev_restore_mode(struct drm_device *dev)
799{
800 int ret;
801 struct drm_i915_private *dev_priv = dev->dev_private;
802
803 if (!dev_priv->fbdev)
804 return;
805
806 ret = drm_fb_helper_restore_fbdev_mode_unlocked(&dev_priv->fbdev->helper);
807 if (ret)
808 DRM_DEBUG("failed to restore crtc mode\n");
809}
810