intel_fbdev.c 22.8 KB
Newer Older
J
Jesse Barnes 已提交
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
/*
 * Copyright © 2007 David Airlie
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *     David Airlie
 */

27
#include <linux/async.h>
J
Jesse Barnes 已提交
28 29
#include <linux/module.h>
#include <linux/kernel.h>
30
#include <linux/console.h>
J
Jesse Barnes 已提交
31 32 33 34 35 36 37
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/init.h>
38
#include <linux/vga_switcheroo.h>
J
Jesse Barnes 已提交
39

40 41 42
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h>
J
Jesse Barnes 已提交
43
#include "intel_drv.h"
44
#include "intel_frontbuffer.h"
45
#include <drm/i915_drm.h>
J
Jesse Barnes 已提交
46 47
#include "i915_drv.h"

48 49 50 51 52 53 54 55
static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
{
	struct drm_i915_gem_object *obj = ifbdev->fb->obj;
	unsigned int origin = ifbdev->vma->fence ? ORIGIN_GTT : ORIGIN_CPU;

	intel_fb_obj_invalidate(obj, origin);
}

56 57 58 59 60 61 62 63
static int intel_fbdev_set_par(struct fb_info *info)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct intel_fbdev *ifbdev =
		container_of(fb_helper, struct intel_fbdev, helper);
	int ret;

	ret = drm_fb_helper_set_par(info);
64 65
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);
66 67 68 69

	return ret;
}

70 71 72 73 74 75 76 77
static int intel_fbdev_blank(int blank, struct fb_info *info)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct intel_fbdev *ifbdev =
		container_of(fb_helper, struct intel_fbdev, helper);
	int ret;

	ret = drm_fb_helper_blank(blank, info);
78 79
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);
80 81 82 83

	return ret;
}

84 85 86 87 88 89 90 91
static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
				   struct fb_info *info)
{
	struct drm_fb_helper *fb_helper = info->par;
	struct intel_fbdev *ifbdev =
		container_of(fb_helper, struct intel_fbdev, helper);
	int ret;

92 93 94
	ret = drm_fb_helper_pan_display(var, info);
	if (ret == 0)
		intel_fbdev_invalidate(ifbdev);
95 96 97 98

	return ret;
}

J
Jesse Barnes 已提交
99 100
static struct fb_ops intelfb_ops = {
	.owner = THIS_MODULE,
101
	DRM_FB_HELPER_DEFAULT_OPS,
102
	.fb_set_par = intel_fbdev_set_par,
103 104 105
	.fb_fillrect = drm_fb_helper_cfb_fillrect,
	.fb_copyarea = drm_fb_helper_cfb_copyarea,
	.fb_imageblit = drm_fb_helper_cfb_imageblit,
106
	.fb_pan_display = intel_fbdev_pan_display,
107
	.fb_blank = intel_fbdev_blank,
J
Jesse Barnes 已提交
108 109
};

110 111
static int intelfb_alloc(struct drm_fb_helper *helper,
			 struct drm_fb_helper_surface_size *sizes)
J
Jesse Barnes 已提交
112
{
113 114
	struct intel_fbdev *ifbdev =
		container_of(helper, struct intel_fbdev, helper);
115
	struct drm_framebuffer *fb;
116
	struct drm_device *dev = helper->dev;
117
	struct drm_i915_private *dev_priv = to_i915(dev);
118
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
119
	struct drm_mode_fb_cmd2 mode_cmd = {};
120
	struct drm_i915_gem_object *obj;
121
	int size, ret;
J
Jesse Barnes 已提交
122

123
	/* we don't do packed 24bpp */
124 125
	if (sizes->surface_bpp == 24)
		sizes->surface_bpp = 32;
126

127 128
	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
J
Jesse Barnes 已提交
129

130 131
	mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
132 133
	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
							  sizes->surface_depth);
J
Jesse Barnes 已提交
134

135
	size = mode_cmd.pitches[0] * mode_cmd.height;
136
	size = PAGE_ALIGN(size);
137 138 139 140

	/* If the FB is too big, just don't use it since fbdev is not very
	 * important and we should probably use that space with FBC or other
	 * features. */
141
	obj = NULL;
142
	if (size * 2 < ggtt->stolen_usable_size)
143
		obj = i915_gem_object_create_stolen(dev_priv, size);
144
	if (obj == NULL)
145
		obj = i915_gem_object_create(dev_priv, size);
146
	if (IS_ERR(obj)) {
147
		DRM_ERROR("failed to allocate framebuffer\n");
148
		ret = PTR_ERR(obj);
149
		goto err;
J
Jesse Barnes 已提交
150 151
	}

152
	fb = intel_framebuffer_create(obj, &mode_cmd);
153 154
	if (IS_ERR(fb)) {
		ret = PTR_ERR(fb);
155
		goto err_obj;
156 157
	}

158
	ifbdev->fb = to_intel_framebuffer(fb);
159 160 161

	return 0;

162 163 164
err_obj:
	i915_gem_object_put(obj);
err:
165 166 167 168 169 170 171 172
	return ret;
}

static int intelfb_create(struct drm_fb_helper *helper,
			  struct drm_fb_helper_surface_size *sizes)
{
	struct intel_fbdev *ifbdev =
		container_of(helper, struct intel_fbdev, helper);
173
	struct intel_framebuffer *intel_fb = ifbdev->fb;
174
	struct drm_device *dev = helper->dev;
175
	struct drm_i915_private *dev_priv = to_i915(dev);
D
David Weinehall 已提交
176
	struct pci_dev *pdev = dev_priv->drm.pdev;
177
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
178 179
	struct fb_info *info;
	struct drm_framebuffer *fb;
180
	struct i915_vma *vma;
181
	bool prealloc = false;
182
	void __iomem *vaddr;
183
	int ret;
184

185 186 187 188 189 190 191
	if (intel_fb &&
	    (sizes->fb_width > intel_fb->base.width ||
	     sizes->fb_height > intel_fb->base.height)) {
		DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
			      " releasing it\n",
			      intel_fb->base.width, intel_fb->base.height,
			      sizes->fb_width, sizes->fb_height);
192
		drm_framebuffer_put(&intel_fb->base);
193 194
		intel_fb = ifbdev->fb = NULL;
	}
195
	if (!intel_fb || WARN_ON(!intel_fb->obj)) {
196
		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
197 198
		ret = intelfb_alloc(helper, sizes);
		if (ret)
199
			return ret;
200
		intel_fb = ifbdev->fb;
201
	} else {
202
		DRM_DEBUG_KMS("re-using BIOS fb\n");
203
		prealloc = true;
204 205 206 207
		sizes->fb_width = intel_fb->base.width;
		sizes->fb_height = intel_fb->base.height;
	}

208
	mutex_lock(&dev->struct_mutex);
209
	intel_runtime_pm_get(dev_priv);
210

211 212 213 214
	/* Pin the GGTT vma for our access via info->screen_base.
	 * This also validates that any existing fb inherited from the
	 * BIOS is suitable for own access.
	 */
215
	vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_MODE_ROTATE_0);
C
Chris Wilson 已提交
216 217
	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
218
		goto out_unlock;
C
Chris Wilson 已提交
219
	}
220

221 222
	info = drm_fb_helper_alloc_fbi(helper);
	if (IS_ERR(info)) {
223
		DRM_ERROR("Failed to allocate fb_info\n");
224
		ret = PTR_ERR(info);
225
		goto out_unpin;
J
Jesse Barnes 已提交
226 227
	}

228
	info->par = helper;
J
Jesse Barnes 已提交
229

230
	fb = &ifbdev->fb->base;
J
Jesse Barnes 已提交
231

232
	ifbdev->helper.fb = fb;
233

J
Jesse Barnes 已提交
234 235 236 237
	strcpy(info->fix.id, "inteldrmfb");

	info->fbops = &intelfb_ops;

238
	/* setup aperture base/size for vesafb takeover */
239
	info->apertures->ranges[0].base = dev->mode_config.fb_base;
240
	info->apertures->ranges[0].size = ggtt->mappable_end;
241

242
	info->fix.smem_start = dev->mode_config.fb_base + i915_ggtt_offset(vma);
243
	info->fix.smem_len = vma->node.size;
J
Jesse Barnes 已提交
244

245 246
	vaddr = i915_vma_pin_iomap(vma);
	if (IS_ERR(vaddr)) {
247
		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
248
		ret = PTR_ERR(vaddr);
249
		goto out_unpin;
J
Jesse Barnes 已提交
250
	}
251 252
	info->screen_base = vaddr;
	info->screen_size = vma->node.size;
J
Jesse Barnes 已提交
253

254 255 256
	/* This driver doesn't need a VT switch to restore the mode on resume */
	info->skip_vt_switch = true;

V
Ville Syrjälä 已提交
257
	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
258
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
J
Jesse Barnes 已提交
259

260 261 262 263
	/* If the object is shmemfs backed, it will have given us zeroed pages.
	 * If the object is stolen however, it will be full of whatever
	 * garbage was left in there.
	 */
C
Chris Wilson 已提交
264
	if (intel_fb->obj->stolen && !prealloc)
265 266
		memset_io(info->screen_base, 0, info->screen_size);

267
	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
J
Jesse Barnes 已提交
268

269 270
	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
		      fb->width, fb->height, i915_ggtt_offset(vma));
C
Chris Wilson 已提交
271
	ifbdev->vma = vma;
J
Jesse Barnes 已提交
272

273
	intel_runtime_pm_put(dev_priv);
J
Jesse Barnes 已提交
274
	mutex_unlock(&dev->struct_mutex);
D
David Weinehall 已提交
275
	vga_switcheroo_client_fb_set(pdev, info);
J
Jesse Barnes 已提交
276 277
	return 0;

278
out_unpin:
279
	intel_unpin_fb_vma(vma);
280
out_unlock:
281
	intel_runtime_pm_put(dev_priv);
J
Jesse Barnes 已提交
282 283 284 285
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
static struct drm_fb_helper_crtc *
intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
{
	int i;

	for (i = 0; i < fb_helper->crtc_count; i++)
		if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
			return &fb_helper->crtc_info[i];

	return NULL;
}

/*
 * Try to read the BIOS display configuration and use it for the initial
 * fb configuration.
 *
 * The BIOS or boot loader will generally create an initial display
 * configuration for us that includes some set of active pipes and displays.
 * This routine tries to figure out which pipes and connectors are active
 * and stuffs them into the crtcs and modes array given to us by the
 * drm_fb_helper code.
 *
 * The overall sequence is:
 *   intel_fbdev_init - from driver load
 *     intel_fbdev_init_bios - initialize the intel_fbdev using BIOS data
 *     drm_fb_helper_init - build fb helper structs
 *     drm_fb_helper_single_add_all_connectors - more fb helper structs
 *   intel_fbdev_initial_config - apply the config
 *     drm_fb_helper_initial_config - call ->probe then register_framebuffer()
 *         drm_setup_crtcs - build crtc config for fbdev
 *           intel_fb_initial_config - find active connectors etc
 *         drm_fb_helper_single_fb_probe - set up fbdev
 *           intelfb_create - re-use or alloc fb, build out fbdev structs
 *
 * Note that we don't make special consideration whether we could actually
 * switch to the selected modes without a full modeset. E.g. when the display
 * is in VGA mode we need to recalculate watermarks and set a new high-res
 * framebuffer anyway.
 */
static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
				    struct drm_fb_helper_crtc **crtcs,
				    struct drm_display_mode **modes,
328
				    struct drm_fb_offset *offsets,
329 330
				    bool *enabled, int width, int height)
{
331
	struct drm_i915_private *dev_priv = to_i915(fb_helper->dev);
332
	unsigned long conn_configured, conn_seq, mask;
333
	unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
334
	int i, j;
335
	bool *save_enabled;
336
	bool fallback = true, ret = true;
337 338
	int num_connectors_enabled = 0;
	int num_connectors_detected = 0;
339
	struct drm_modeset_acquire_ctx ctx;
340

341
	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
342 343 344
	if (!save_enabled)
		return false;

345 346 347 348 349
	drm_modeset_acquire_init(&ctx, 0);

	while (drm_modeset_lock_all_ctx(fb_helper->dev, &ctx) != 0)
		drm_modeset_backoff(&ctx);

350
	memcpy(save_enabled, enabled, count);
351
	mask = GENMASK(count - 1, 0);
352
	conn_configured = 0;
353
retry:
354
	conn_seq = conn_configured;
355
	for (i = 0; i < count; i++) {
356 357 358 359 360 361 362
		struct drm_fb_helper_connector *fb_conn;
		struct drm_connector *connector;
		struct drm_encoder *encoder;
		struct drm_fb_helper_crtc *new_crtc;

		fb_conn = fb_helper->connector_info[i];
		connector = fb_conn->connector;
363

364
		if (conn_configured & BIT(i))
365 366
			continue;

367
		if (conn_seq == 0 && !connector->has_tile)
368 369
			continue;

370 371 372
		if (connector->status == connector_status_connected)
			num_connectors_detected++;

373
		if (!enabled[i]) {
374
			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
375
				      connector->name);
376
			conn_configured |= BIT(i);
377 378 379
			continue;
		}

380 381 382 383 384 385 386
		if (connector->force == DRM_FORCE_OFF) {
			DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
				      connector->name);
			enabled[i] = false;
			continue;
		}

387 388
		encoder = connector->state->best_encoder;
		if (!encoder || WARN_ON(!connector->state->crtc)) {
389 390 391
			if (connector->force > DRM_FORCE_OFF)
				goto bail;

392
			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
393
				      connector->name);
394
			enabled[i] = false;
395
			conn_configured |= BIT(i);
396 397 398
			continue;
		}

399 400
		num_connectors_enabled++;

401 402
		new_crtc = intel_fb_helper_crtc(fb_helper,
						connector->state->crtc);
403 404 405 406 407 408

		/*
		 * Make sure we're not trying to drive multiple connectors
		 * with a single CRTC, since our cloning support may not
		 * match the BIOS.
		 */
409
		for (j = 0; j < count; j++) {
410
			if (crtcs[j] == new_crtc) {
411
				DRM_DEBUG_KMS("fallback: cloned configuration\n");
412
				goto bail;
413
			}
414 415
		}

416
		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
417
			      connector->name);
418 419

		/* go for command line mode first */
420
		modes[i] = drm_pick_cmdline_mode(fb_conn);
421 422 423

		/* try for preferred next */
		if (!modes[i]) {
424 425
			DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
				      connector->name, connector->has_tile);
426 427 428 429
			modes[i] = drm_has_preferred_mode(fb_conn, width,
							  height);
		}

430 431 432
		/* No preferred mode marked by the EDID? Are there any modes? */
		if (!modes[i] && !list_empty(&connector->modes)) {
			DRM_DEBUG_KMS("using first mode listed on connector %s\n",
433
				      connector->name);
434 435 436 437 438
			modes[i] = list_first_entry(&connector->modes,
						    struct drm_display_mode,
						    head);
		}

439 440 441 442 443 444
		/* last resort: use current mode */
		if (!modes[i]) {
			/*
			 * IMPORTANT: We want to use the adjusted mode (i.e.
			 * after the panel fitter upscaling) as the initial
			 * config, not the input mode, which is what crtc->mode
445
			 * usually contains. But since our current
446
			 * code puts a mode derived from the post-pfit timings
447
			 * into crtc->mode this works out correctly.
448 449 450 451 452
			 *
			 * This is crtc->mode and not crtc->state->mode for the
			 * fastboot check to work correctly. crtc_state->mode has
			 * I915_MODE_FLAG_INHERITED, which we clear to force check
			 * state.
453
			 */
454
			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
455
				      connector->name);
456
			modes[i] = &connector->state->crtc->mode;
457 458 459
		}
		crtcs[i] = new_crtc;

460
		DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
461
			      connector->name,
462
			      connector->state->crtc->base.id,
463
			      connector->state->crtc->name,
464 465
			      modes[i]->hdisplay, modes[i]->vdisplay,
			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
466

467
		fallback = false;
468
		conn_configured |= BIT(i);
469 470
	}

471
	if ((conn_configured & mask) != mask && conn_configured != conn_seq)
472
		goto retry;
473

474 475 476 477 478 479
	/*
	 * If the BIOS didn't enable everything it could, fall back to have the
	 * same user experiencing of lighting up as much as possible like the
	 * fbdev helper library.
	 */
	if (num_connectors_enabled != num_connectors_detected &&
480
	    num_connectors_enabled < INTEL_INFO(dev_priv)->num_pipes) {
481 482 483 484 485 486
		DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
		DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
			      num_connectors_detected);
		fallback = true;
	}

487
	if (fallback) {
488
bail:
489
		DRM_DEBUG_KMS("Not using firmware configuration\n");
490
		memcpy(enabled, save_enabled, count);
491
		ret = false;
492 493
	}

494 495 496
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);

497
	kfree(save_enabled);
498
	return ret;
499 500
}

501
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
502
	.initial_config = intel_fb_initial_config,
503
	.fb_probe = intelfb_create,
504
};
J
Jesse Barnes 已提交
505

506
static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
J
Jesse Barnes 已提交
507
{
508 509 510 511
	/* We rely on the object-free to release the VMA pinning for
	 * the info->screen_base mmaping. Leaking the VMA is simpler than
	 * trying to rectify all the possible error paths leading here.
	 */
512

513
	drm_fb_helper_fini(&ifbdev->helper);
J
Jesse Barnes 已提交
514

515
	if (ifbdev->vma) {
516
		mutex_lock(&ifbdev->helper.dev->struct_mutex);
517
		intel_unpin_fb_vma(ifbdev->vma);
518
		mutex_unlock(&ifbdev->helper.dev->struct_mutex);
519
	}
520

521
	if (ifbdev->fb)
522
		drm_framebuffer_remove(&ifbdev->fb->base);
523 524

	kfree(ifbdev);
J
Jesse Barnes 已提交
525
}
526

527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
/*
 * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
 * The core display code will have read out the current plane configuration,
 * so we use that to figure out if there's an object for us to use as the
 * fb, and if so, we re-use it for the fbdev configuration.
 *
 * Note we only support a single fb shared across pipes for boot (mostly for
 * fbcon), so we just find the biggest and use that.
 */
static bool intel_fbdev_init_bios(struct drm_device *dev,
				 struct intel_fbdev *ifbdev)
{
	struct intel_framebuffer *fb = NULL;
	struct drm_crtc *crtc;
	struct intel_crtc *intel_crtc;
	unsigned int max_size = 0;

	/* Find the largest fb */
545
	for_each_crtc(dev, crtc) {
546 547
		struct drm_i915_gem_object *obj =
			intel_fb_obj(crtc->primary->state->fb);
548 549
		intel_crtc = to_intel_crtc(crtc);

550
		if (!crtc->state->active || !obj) {
551 552 553 554 555
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
				      pipe_name(intel_crtc->pipe));
			continue;
		}

556
		if (obj->base.size > max_size) {
557 558
			DRM_DEBUG_KMS("found possible fb from plane %c\n",
				      pipe_name(intel_crtc->pipe));
559 560
			fb = to_intel_framebuffer(crtc->primary->state->fb);
			max_size = obj->base.size;
561 562 563 564 565 566 567 568 569
		}
	}

	if (!fb) {
		DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
		goto out;
	}

	/* Now make sure all the pipes will fit into it */
570
	for_each_crtc(dev, crtc) {
571 572 573 574
		unsigned int cur_size;

		intel_crtc = to_intel_crtc(crtc);

575
		if (!crtc->state->active) {
576 577 578 579 580 581 582 583 584 585
			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
				      pipe_name(intel_crtc->pipe));
			continue;
		}

		DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
			      pipe_name(intel_crtc->pipe));

		/*
		 * See if the plane fb we found above will fit on this
586 587
		 * pipe.  Note we need to use the selected fb's pitch and bpp
		 * rather than the current pipe's, since they differ.
588
		 */
589
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
V
Ville Syrjälä 已提交
590
		cur_size = cur_size * fb->base.format->cpp[0];
591 592 593 594 595 596 597 598
		if (fb->base.pitches[0] < cur_size) {
			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
				      pipe_name(intel_crtc->pipe),
				      cur_size, fb->base.pitches[0]);
			fb = NULL;
			break;
		}

599
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
600
		cur_size = intel_fb_align_height(&fb->base, 0, cur_size);
601 602 603
		cur_size *= fb->base.pitches[0];
		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
			      pipe_name(intel_crtc->pipe),
604 605
			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
V
Ville Syrjälä 已提交
606
			      fb->base.format->cpp[0] * 8,
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
			      cur_size);

		if (cur_size > max_size) {
			DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
				      pipe_name(intel_crtc->pipe),
				      cur_size, max_size);
			fb = NULL;
			break;
		}

		DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
			      pipe_name(intel_crtc->pipe),
			      max_size, cur_size);
	}

	if (!fb) {
		DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
		goto out;
	}

V
Ville Syrjälä 已提交
627
	ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8;
628 629
	ifbdev->fb = fb;

630
	drm_framebuffer_get(&ifbdev->fb->base);
631 632

	/* Final pass to check if any active pipes don't have fbs */
633
	for_each_crtc(dev, crtc) {
634 635
		intel_crtc = to_intel_crtc(crtc);

636
		if (!crtc->state->active)
637 638
			continue;

639
		WARN(!crtc->primary->fb,
640 641 642 643 644 645 646 647 648 649 650 651 652
		     "re-used BIOS config but lost an fb on crtc %d\n",
		     crtc->base.id);
	}


	DRM_DEBUG_KMS("using BIOS fb for initial console\n");
	return true;

out:

	return false;
}

653 654
static void intel_fbdev_suspend_worker(struct work_struct *work)
{
655 656 657
	intel_fbdev_set_suspend(&container_of(work,
					      struct drm_i915_private,
					      fbdev_suspend_work)->drm,
658 659 660 661
				FBINFO_STATE_RUNNING,
				true);
}

662 663
int intel_fbdev_init(struct drm_device *dev)
{
664
	struct drm_i915_private *dev_priv = to_i915(dev);
665
	struct intel_fbdev *ifbdev;
666
	int ret;
667

668
	if (WARN_ON(INTEL_INFO(dev_priv)->num_pipes == 0))
669 670 671 672
		return -ENODEV;

	ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
	if (ifbdev == NULL)
673 674
		return -ENOMEM;

675 676
	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);

677 678
	if (!intel_fbdev_init_bios(dev, ifbdev))
		ifbdev->preferred_bpp = 32;
679

680
	ret = drm_fb_helper_init(dev, &ifbdev->helper, 4);
681 682 683 684
	if (ret) {
		kfree(ifbdev);
		return ret;
	}
685

686
	dev_priv->fbdev = ifbdev;
687 688
	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);

689
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
690

J
Jesse Barnes 已提交
691 692
	return 0;
}
693

694
static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
695
{
696
	struct intel_fbdev *ifbdev = data;
697 698

	/* Due to peculiar init order wrt to hpd handling this is separate. */
699
	if (drm_fb_helper_initial_config(&ifbdev->helper,
700
					 ifbdev->preferred_bpp))
701
		intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
702 703
}

704 705
void intel_fbdev_initial_config_async(struct drm_device *dev)
{
706 707
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

708 709 710
	if (!ifbdev)
		return;

711 712 713 714 715 716 717 718 719 720 721
	ifbdev->cookie = async_schedule(intel_fbdev_initial_config, ifbdev);
}

static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
{
	if (!ifbdev->cookie)
		return;

	/* Only serialises with all preceding async calls, hence +1 */
	async_synchronize_cookie(ifbdev->cookie + 1);
	ifbdev->cookie = 0;
722 723
}

724
void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
725
{
726 727 728
	struct intel_fbdev *ifbdev = dev_priv->fbdev;

	if (!ifbdev)
729 730
		return;

731
	cancel_work_sync(&dev_priv->fbdev_suspend_work);
732
	if (!current_is_async())
733 734
		intel_fbdev_sync(ifbdev);

735 736 737 738 739 740 741 742 743 744
	drm_fb_helper_unregister_fbi(&ifbdev->helper);
}

void intel_fbdev_fini(struct drm_i915_private *dev_priv)
{
	struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev);

	if (!ifbdev)
		return;

745
	intel_fbdev_destroy(ifbdev);
746
}
747

748
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
749
{
750
	struct drm_i915_private *dev_priv = to_i915(dev);
751 752 753
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct fb_info *info;

754
	if (!ifbdev || !ifbdev->vma)
755 756
		return;

757 758
	info = ifbdev->helper.fbdev;

759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
	if (synchronous) {
		/* Flush any pending work to turn the console on, and then
		 * wait to turn it off. It must be synchronous as we are
		 * about to suspend or unload the driver.
		 *
		 * Note that from within the work-handler, we cannot flush
		 * ourselves, so only flush outstanding work upon suspend!
		 */
		if (state != FBINFO_STATE_RUNNING)
			flush_work(&dev_priv->fbdev_suspend_work);
		console_lock();
	} else {
		/*
		 * The console lock can be pretty contented on resume due
		 * to all the printk activity.  Try to keep it out of the hot
		 * path of resume if possible.
		 */
		WARN_ON(state != FBINFO_STATE_RUNNING);
		if (!console_trylock()) {
			/* Don't block our own workqueue as this can
			 * be run in parallel with other i915.ko tasks.
			 */
			schedule_work(&dev_priv->fbdev_suspend_work);
			return;
		}
	}

786 787 788 789
	/* On resume from hibernation: If the object is shmemfs backed, it has
	 * been restored from swap. If the object is stolen however, it will be
	 * full of whatever garbage was left in there.
	 */
790
	if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
791 792
		memset_io(info->screen_base, 0, info->screen_size);

793
	drm_fb_helper_set_suspend(&ifbdev->helper, state);
794
	console_unlock();
795 796
}

797
void intel_fbdev_output_poll_changed(struct drm_device *dev)
798
{
799 800
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

801 802 803 804 805
	if (!ifbdev)
		return;

	intel_fbdev_sync(ifbdev);
	if (ifbdev->vma)
806
		drm_fb_helper_hotplug_event(&ifbdev->helper);
807
}
808

809
void intel_fbdev_restore_mode(struct drm_device *dev)
810
{
811
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
812

813
	if (!ifbdev)
B
Ben Widawsky 已提交
814 815
		return;

816
	intel_fbdev_sync(ifbdev);
817
	if (!ifbdev->vma)
818
		return;
819

820 821
	if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
		intel_fbdev_invalidate(ifbdev);
822
}