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/console.h>
29#include <linux/delay.h>
30#include <linux/errno.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_fb_helper.h>
42#include <drm/drm_fourcc.h>
43#include <drm/i915_drm.h>
44
45#include "i915_drv.h"
46#include "intel_drv.h"
47#include "intel_fbdev.h"
48#include "intel_frontbuffer.h"
49
50static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
51{
52 struct drm_i915_gem_object *obj = intel_fb_obj(&ifbdev->fb->base);
53 unsigned int origin =
54 ifbdev->vma_flags & PLANE_HAS_FENCE ? ORIGIN_GTT : ORIGIN_CPU;
55
56 intel_fb_obj_invalidate(obj, origin);
57}
58
59static int intel_fbdev_set_par(struct fb_info *info)
60{
61 struct drm_fb_helper *fb_helper = info->par;
62 struct intel_fbdev *ifbdev =
63 container_of(fb_helper, struct intel_fbdev, helper);
64 int ret;
65
66 ret = drm_fb_helper_set_par(info);
67 if (ret == 0)
68 intel_fbdev_invalidate(ifbdev);
69
70 return ret;
71}
72
73static int intel_fbdev_blank(int blank, struct fb_info *info)
74{
75 struct drm_fb_helper *fb_helper = info->par;
76 struct intel_fbdev *ifbdev =
77 container_of(fb_helper, struct intel_fbdev, helper);
78 int ret;
79
80 ret = drm_fb_helper_blank(blank, info);
81 if (ret == 0)
82 intel_fbdev_invalidate(ifbdev);
83
84 return ret;
85}
86
87static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
88 struct fb_info *info)
89{
90 struct drm_fb_helper *fb_helper = info->par;
91 struct intel_fbdev *ifbdev =
92 container_of(fb_helper, struct intel_fbdev, helper);
93 int ret;
94
95 ret = drm_fb_helper_pan_display(var, info);
96 if (ret == 0)
97 intel_fbdev_invalidate(ifbdev);
98
99 return ret;
100}
101
102static struct fb_ops intelfb_ops = {
103 .owner = THIS_MODULE,
104 DRM_FB_HELPER_DEFAULT_OPS,
105 .fb_set_par = intel_fbdev_set_par,
106 .fb_fillrect = drm_fb_helper_cfb_fillrect,
107 .fb_copyarea = drm_fb_helper_cfb_copyarea,
108 .fb_imageblit = drm_fb_helper_cfb_imageblit,
109 .fb_pan_display = intel_fbdev_pan_display,
110 .fb_blank = intel_fbdev_blank,
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_i915_private *dev_priv = to_i915(dev);
121 struct drm_mode_fb_cmd2 mode_cmd = {};
122 struct drm_i915_gem_object *obj;
123 int size, ret;
124
125
126 if (sizes->surface_bpp == 24)
127 sizes->surface_bpp = 32;
128
129 mode_cmd.width = sizes->surface_width;
130 mode_cmd.height = sizes->surface_height;
131
132 mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
133 DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
134 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
135 sizes->surface_depth);
136
137 size = mode_cmd.pitches[0] * mode_cmd.height;
138 size = PAGE_ALIGN(size);
139
140
141
142
143 obj = NULL;
144 if (size * 2 < dev_priv->stolen_usable_size)
145 obj = i915_gem_object_create_stolen(dev_priv, size);
146 if (obj == NULL)
147 obj = i915_gem_object_create_shmem(dev_priv, size);
148 if (IS_ERR(obj)) {
149 DRM_ERROR("failed to allocate framebuffer\n");
150 ret = PTR_ERR(obj);
151 goto err;
152 }
153
154 fb = intel_framebuffer_create(obj, &mode_cmd);
155 if (IS_ERR(fb)) {
156 ret = PTR_ERR(fb);
157 goto err_obj;
158 }
159
160 ifbdev->fb = to_intel_framebuffer(fb);
161
162 return 0;
163
164err_obj:
165 i915_gem_object_put(obj);
166err:
167 return ret;
168}
169
170static int intelfb_create(struct drm_fb_helper *helper,
171 struct drm_fb_helper_surface_size *sizes)
172{
173 struct intel_fbdev *ifbdev =
174 container_of(helper, struct intel_fbdev, helper);
175 struct intel_framebuffer *intel_fb = ifbdev->fb;
176 struct drm_device *dev = helper->dev;
177 struct drm_i915_private *dev_priv = to_i915(dev);
178 struct pci_dev *pdev = dev_priv->drm.pdev;
179 struct i915_ggtt *ggtt = &dev_priv->ggtt;
180 const struct i915_ggtt_view view = {
181 .type = I915_GGTT_VIEW_NORMAL,
182 };
183 struct drm_framebuffer *fb;
184 intel_wakeref_t wakeref;
185 struct fb_info *info;
186 struct i915_vma *vma;
187 unsigned long flags = 0;
188 bool prealloc = false;
189 void __iomem *vaddr;
190 int ret;
191
192 if (intel_fb &&
193 (sizes->fb_width > intel_fb->base.width ||
194 sizes->fb_height > intel_fb->base.height)) {
195 DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
196 " releasing it\n",
197 intel_fb->base.width, intel_fb->base.height,
198 sizes->fb_width, sizes->fb_height);
199 drm_framebuffer_put(&intel_fb->base);
200 intel_fb = ifbdev->fb = NULL;
201 }
202 if (!intel_fb || WARN_ON(!intel_fb_obj(&intel_fb->base))) {
203 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
204 ret = intelfb_alloc(helper, sizes);
205 if (ret)
206 return ret;
207 intel_fb = ifbdev->fb;
208 } else {
209 DRM_DEBUG_KMS("re-using BIOS fb\n");
210 prealloc = true;
211 sizes->fb_width = intel_fb->base.width;
212 sizes->fb_height = intel_fb->base.height;
213 }
214
215 mutex_lock(&dev->struct_mutex);
216 wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
217
218
219
220
221
222 vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base,
223 &view, false, &flags);
224 if (IS_ERR(vma)) {
225 ret = PTR_ERR(vma);
226 goto out_unlock;
227 }
228
229 fb = &ifbdev->fb->base;
230 intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
231
232 info = drm_fb_helper_alloc_fbi(helper);
233 if (IS_ERR(info)) {
234 DRM_ERROR("Failed to allocate fb_info\n");
235 ret = PTR_ERR(info);
236 goto out_unpin;
237 }
238
239 ifbdev->helper.fb = fb;
240
241 info->fbops = &intelfb_ops;
242
243
244 info->apertures->ranges[0].base = dev->mode_config.fb_base;
245 info->apertures->ranges[0].size = ggtt->mappable_end;
246
247 info->fix.smem_start = dev->mode_config.fb_base + i915_ggtt_offset(vma);
248 info->fix.smem_len = vma->node.size;
249
250 vaddr = i915_vma_pin_iomap(vma);
251 if (IS_ERR(vaddr)) {
252 DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
253 ret = PTR_ERR(vaddr);
254 goto out_unpin;
255 }
256 info->screen_base = vaddr;
257 info->screen_size = vma->node.size;
258
259 drm_fb_helper_fill_info(info, &ifbdev->helper, sizes);
260
261
262
263
264
265 if (intel_fb_obj(fb)->stolen && !prealloc)
266 memset_io(info->screen_base, 0, info->screen_size);
267
268
269
270 DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
271 fb->width, fb->height, i915_ggtt_offset(vma));
272 ifbdev->vma = vma;
273 ifbdev->vma_flags = flags;
274
275 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
276 mutex_unlock(&dev->struct_mutex);
277 vga_switcheroo_client_fb_set(pdev, info);
278 return 0;
279
280out_unpin:
281 intel_unpin_fb_vma(vma, flags);
282out_unlock:
283 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
284 mutex_unlock(&dev->struct_mutex);
285 return ret;
286}
287
288static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
289 .fb_probe = intelfb_create,
290};
291
292static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
293{
294
295
296
297
298
299 drm_fb_helper_fini(&ifbdev->helper);
300
301 if (ifbdev->vma) {
302 mutex_lock(&ifbdev->helper.dev->struct_mutex);
303 intel_unpin_fb_vma(ifbdev->vma, ifbdev->vma_flags);
304 mutex_unlock(&ifbdev->helper.dev->struct_mutex);
305 }
306
307 if (ifbdev->fb)
308 drm_framebuffer_remove(&ifbdev->fb->base);
309
310 kfree(ifbdev);
311}
312
313
314
315
316
317
318
319
320
321
322static bool intel_fbdev_init_bios(struct drm_device *dev,
323 struct intel_fbdev *ifbdev)
324{
325 struct intel_framebuffer *fb = NULL;
326 struct drm_crtc *crtc;
327 struct intel_crtc *intel_crtc;
328 unsigned int max_size = 0;
329
330
331 for_each_crtc(dev, crtc) {
332 struct drm_i915_gem_object *obj =
333 intel_fb_obj(crtc->primary->state->fb);
334 intel_crtc = to_intel_crtc(crtc);
335
336 if (!crtc->state->active || !obj) {
337 DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
338 pipe_name(intel_crtc->pipe));
339 continue;
340 }
341
342 if (obj->base.size > max_size) {
343 DRM_DEBUG_KMS("found possible fb from plane %c\n",
344 pipe_name(intel_crtc->pipe));
345 fb = to_intel_framebuffer(crtc->primary->state->fb);
346 max_size = obj->base.size;
347 }
348 }
349
350 if (!fb) {
351 DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
352 goto out;
353 }
354
355
356 for_each_crtc(dev, crtc) {
357 unsigned int cur_size;
358
359 intel_crtc = to_intel_crtc(crtc);
360
361 if (!crtc->state->active) {
362 DRM_DEBUG_KMS("pipe %c not active, skipping\n",
363 pipe_name(intel_crtc->pipe));
364 continue;
365 }
366
367 DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
368 pipe_name(intel_crtc->pipe));
369
370
371
372
373
374
375 cur_size = crtc->state->adjusted_mode.crtc_hdisplay;
376 cur_size = cur_size * fb->base.format->cpp[0];
377 if (fb->base.pitches[0] < cur_size) {
378 DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
379 pipe_name(intel_crtc->pipe),
380 cur_size, fb->base.pitches[0]);
381 fb = NULL;
382 break;
383 }
384
385 cur_size = crtc->state->adjusted_mode.crtc_vdisplay;
386 cur_size = intel_fb_align_height(&fb->base, 0, cur_size);
387 cur_size *= fb->base.pitches[0];
388 DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
389 pipe_name(intel_crtc->pipe),
390 crtc->state->adjusted_mode.crtc_hdisplay,
391 crtc->state->adjusted_mode.crtc_vdisplay,
392 fb->base.format->cpp[0] * 8,
393 cur_size);
394
395 if (cur_size > max_size) {
396 DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
397 pipe_name(intel_crtc->pipe),
398 cur_size, max_size);
399 fb = NULL;
400 break;
401 }
402
403 DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
404 pipe_name(intel_crtc->pipe),
405 max_size, cur_size);
406 }
407
408 if (!fb) {
409 DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
410 goto out;
411 }
412
413 ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8;
414 ifbdev->fb = fb;
415
416 drm_framebuffer_get(&ifbdev->fb->base);
417
418
419 for_each_crtc(dev, crtc) {
420 intel_crtc = to_intel_crtc(crtc);
421
422 if (!crtc->state->active)
423 continue;
424
425 WARN(!crtc->primary->state->fb,
426 "re-used BIOS config but lost an fb on crtc %d\n",
427 crtc->base.id);
428 }
429
430
431 DRM_DEBUG_KMS("using BIOS fb for initial console\n");
432 return true;
433
434out:
435
436 return false;
437}
438
439static void intel_fbdev_suspend_worker(struct work_struct *work)
440{
441 intel_fbdev_set_suspend(&container_of(work,
442 struct drm_i915_private,
443 fbdev_suspend_work)->drm,
444 FBINFO_STATE_RUNNING,
445 true);
446}
447
448int intel_fbdev_init(struct drm_device *dev)
449{
450 struct drm_i915_private *dev_priv = to_i915(dev);
451 struct intel_fbdev *ifbdev;
452 int ret;
453
454 if (WARN_ON(!HAS_DISPLAY(dev_priv)))
455 return -ENODEV;
456
457 ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
458 if (ifbdev == NULL)
459 return -ENOMEM;
460
461 mutex_init(&ifbdev->hpd_lock);
462 drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
463
464 if (!intel_fbdev_init_bios(dev, ifbdev))
465 ifbdev->preferred_bpp = 32;
466
467 ret = drm_fb_helper_init(dev, &ifbdev->helper, 4);
468 if (ret) {
469 kfree(ifbdev);
470 return ret;
471 }
472
473 dev_priv->fbdev = ifbdev;
474 INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
475
476 drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
477
478 return 0;
479}
480
481static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
482{
483 struct intel_fbdev *ifbdev = data;
484
485
486 if (drm_fb_helper_initial_config(&ifbdev->helper,
487 ifbdev->preferred_bpp))
488 intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
489}
490
491void intel_fbdev_initial_config_async(struct drm_device *dev)
492{
493 struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
494
495 if (!ifbdev)
496 return;
497
498 ifbdev->cookie = async_schedule(intel_fbdev_initial_config, ifbdev);
499}
500
501static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
502{
503 if (!ifbdev->cookie)
504 return;
505
506
507 async_synchronize_cookie(ifbdev->cookie + 1);
508 ifbdev->cookie = 0;
509}
510
511void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
512{
513 struct intel_fbdev *ifbdev = dev_priv->fbdev;
514
515 if (!ifbdev)
516 return;
517
518 cancel_work_sync(&dev_priv->fbdev_suspend_work);
519 if (!current_is_async())
520 intel_fbdev_sync(ifbdev);
521
522 drm_fb_helper_unregister_fbi(&ifbdev->helper);
523}
524
525void intel_fbdev_fini(struct drm_i915_private *dev_priv)
526{
527 struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev);
528
529 if (!ifbdev)
530 return;
531
532 intel_fbdev_destroy(ifbdev);
533}
534
535
536
537
538
539static void intel_fbdev_hpd_set_suspend(struct intel_fbdev *ifbdev, int state)
540{
541 bool send_hpd = false;
542
543 mutex_lock(&ifbdev->hpd_lock);
544 ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED;
545 send_hpd = !ifbdev->hpd_suspended && ifbdev->hpd_waiting;
546 ifbdev->hpd_waiting = false;
547 mutex_unlock(&ifbdev->hpd_lock);
548
549 if (send_hpd) {
550 DRM_DEBUG_KMS("Handling delayed fbcon HPD event\n");
551 drm_fb_helper_hotplug_event(&ifbdev->helper);
552 }
553}
554
555void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
556{
557 struct drm_i915_private *dev_priv = to_i915(dev);
558 struct intel_fbdev *ifbdev = dev_priv->fbdev;
559 struct fb_info *info;
560
561 if (!ifbdev || !ifbdev->vma)
562 return;
563
564 info = ifbdev->helper.fbdev;
565
566 if (synchronous) {
567
568
569
570
571
572
573
574 if (state != FBINFO_STATE_RUNNING)
575 flush_work(&dev_priv->fbdev_suspend_work);
576
577 console_lock();
578 } else {
579
580
581
582
583
584 WARN_ON(state != FBINFO_STATE_RUNNING);
585 if (!console_trylock()) {
586
587
588
589 schedule_work(&dev_priv->fbdev_suspend_work);
590 return;
591 }
592 }
593
594
595
596
597
598 if (state == FBINFO_STATE_RUNNING &&
599 intel_fb_obj(&ifbdev->fb->base)->stolen)
600 memset_io(info->screen_base, 0, info->screen_size);
601
602 drm_fb_helper_set_suspend(&ifbdev->helper, state);
603 console_unlock();
604
605 intel_fbdev_hpd_set_suspend(ifbdev, state);
606}
607
608void intel_fbdev_output_poll_changed(struct drm_device *dev)
609{
610 struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
611 bool send_hpd;
612
613 if (!ifbdev)
614 return;
615
616 intel_fbdev_sync(ifbdev);
617
618 mutex_lock(&ifbdev->hpd_lock);
619 send_hpd = !ifbdev->hpd_suspended;
620 ifbdev->hpd_waiting = true;
621 mutex_unlock(&ifbdev->hpd_lock);
622
623 if (send_hpd && (ifbdev->vma || ifbdev->helper.deferred_setup))
624 drm_fb_helper_hotplug_event(&ifbdev->helper);
625}
626
627void intel_fbdev_restore_mode(struct drm_device *dev)
628{
629 struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
630
631 if (!ifbdev)
632 return;
633
634 intel_fbdev_sync(ifbdev);
635 if (!ifbdev->vma)
636 return;
637
638 if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
639 intel_fbdev_invalidate(ifbdev);
640}
641