intel_fbdev.c 23.3 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 192 193 194
	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);
		drm_framebuffer_unreference(&intel_fb->base);
		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 209
	mutex_lock(&dev->struct_mutex);

210 211 212 213
	/* 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.
	 */
C
Chris Wilson 已提交
214 215 216
	vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
217
		goto out_unlock;
C
Chris Wilson 已提交
218
	}
219

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

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

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

231
	ifbdev->helper.fb = fb;
232

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

235
	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
J
Jesse Barnes 已提交
236 237
	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

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

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

284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
/** Sets the color ramps on behalf of RandR */
static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
				    u16 blue, int regno)
{
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	intel_crtc->lut_r[regno] = red >> 8;
	intel_crtc->lut_g[regno] = green >> 8;
	intel_crtc->lut_b[regno] = blue >> 8;
}

static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
				    u16 *blue, int regno)
{
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	*red = intel_crtc->lut_r[regno] << 8;
	*green = intel_crtc->lut_g[regno] << 8;
	*blue = intel_crtc->lut_b[regno] << 8;
}

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 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
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,
347
				    struct drm_fb_offset *offsets,
348 349
				    bool *enabled, int width, int height)
{
350
	struct drm_i915_private *dev_priv = to_i915(fb_helper->dev);
351
	unsigned long conn_configured, conn_seq, mask;
352
	unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
353
	int i, j;
354
	bool *save_enabled;
355
	bool fallback = true;
356 357
	int num_connectors_enabled = 0;
	int num_connectors_detected = 0;
358

359
	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
360 361 362
	if (!save_enabled)
		return false;

363
	memcpy(save_enabled, enabled, count);
364
	mask = GENMASK(count - 1, 0);
365
	conn_configured = 0;
366
retry:
367
	conn_seq = conn_configured;
368
	for (i = 0; i < count; i++) {
369 370 371 372
		struct drm_fb_helper_connector *fb_conn;
		struct drm_connector *connector;
		struct drm_encoder *encoder;
		struct drm_fb_helper_crtc *new_crtc;
373
		struct intel_crtc *intel_crtc;
374 375 376

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

378
		if (conn_configured & BIT(i))
379 380
			continue;

381
		if (conn_seq == 0 && !connector->has_tile)
382 383
			continue;

384 385 386
		if (connector->status == connector_status_connected)
			num_connectors_detected++;

387
		if (!enabled[i]) {
388
			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
389
				      connector->name);
390
			conn_configured |= BIT(i);
391 392 393
			continue;
		}

394 395 396 397 398 399 400
		if (connector->force == DRM_FORCE_OFF) {
			DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
				      connector->name);
			enabled[i] = false;
			continue;
		}

401 402
		encoder = connector->state->best_encoder;
		if (!encoder || WARN_ON(!connector->state->crtc)) {
403 404 405
			if (connector->force > DRM_FORCE_OFF)
				goto bail;

406
			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
407
				      connector->name);
408
			enabled[i] = false;
409
			conn_configured |= BIT(i);
410 411 412
			continue;
		}

413 414
		num_connectors_enabled++;

415 416 417 418 419 420 421
		intel_crtc = to_intel_crtc(connector->state->crtc);
		for (j = 0; j < 256; j++) {
			intel_crtc->lut_r[j] = j;
			intel_crtc->lut_g[j] = j;
			intel_crtc->lut_b[j] = j;
		}

422 423
		new_crtc = intel_fb_helper_crtc(fb_helper,
						connector->state->crtc);
424 425 426 427 428 429

		/*
		 * Make sure we're not trying to drive multiple connectors
		 * with a single CRTC, since our cloning support may not
		 * match the BIOS.
		 */
430
		for (j = 0; j < count; j++) {
431
			if (crtcs[j] == new_crtc) {
432
				DRM_DEBUG_KMS("fallback: cloned configuration\n");
433
				goto bail;
434
			}
435 436
		}

437
		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
438
			      connector->name);
439 440

		/* go for command line mode first */
441
		modes[i] = drm_pick_cmdline_mode(fb_conn);
442 443 444

		/* try for preferred next */
		if (!modes[i]) {
445 446
			DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
				      connector->name, connector->has_tile);
447 448 449 450
			modes[i] = drm_has_preferred_mode(fb_conn, width,
							  height);
		}

451 452 453
		/* 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",
454
				      connector->name);
455 456 457 458 459
			modes[i] = list_first_entry(&connector->modes,
						    struct drm_display_mode,
						    head);
		}

460 461 462 463 464 465
		/* 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
466
			 * usually contains. But since our current
467
			 * code puts a mode derived from the post-pfit timings
468
			 * into crtc->mode this works out correctly.
469 470 471 472 473
			 *
			 * 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.
474
			 */
475
			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
476
				      connector->name);
477
			modes[i] = &connector->state->crtc->mode;
478 479 480
		}
		crtcs[i] = new_crtc;

481
		DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
482
			      connector->name,
483
			      connector->state->crtc->base.id,
484
			      connector->state->crtc->name,
485 486
			      modes[i]->hdisplay, modes[i]->vdisplay,
			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
487

488
		fallback = false;
489
		conn_configured |= BIT(i);
490 491
	}

492
	if ((conn_configured & mask) != mask && conn_configured != conn_seq)
493
		goto retry;
494

495 496 497 498 499 500
	/*
	 * 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 &&
501
	    num_connectors_enabled < INTEL_INFO(dev_priv)->num_pipes) {
502 503 504 505 506 507
		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;
	}

508
	if (fallback) {
509
bail:
510
		DRM_DEBUG_KMS("Not using firmware configuration\n");
511
		memcpy(enabled, save_enabled, count);
512 513
		kfree(save_enabled);
		return false;
514 515
	}

516
	kfree(save_enabled);
517 518 519
	return true;
}

520
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
521
	.initial_config = intel_fb_initial_config,
522 523
	.gamma_set = intel_crtc_fb_gamma_set,
	.gamma_get = intel_crtc_fb_gamma_get,
524
	.fb_probe = intelfb_create,
525
};
J
Jesse Barnes 已提交
526

527
static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
J
Jesse Barnes 已提交
528
{
529 530 531 532
	/* 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.
	 */
533

534
	drm_fb_helper_unregister_fbi(&ifbdev->helper);
J
Jesse Barnes 已提交
535

536
	drm_fb_helper_fini(&ifbdev->helper);
J
Jesse Barnes 已提交
537

538
	if (ifbdev->fb) {
539
		mutex_lock(&ifbdev->helper.dev->struct_mutex);
540
		intel_unpin_fb_vma(ifbdev->vma);
541
		mutex_unlock(&ifbdev->helper.dev->struct_mutex);
542

543 544
		drm_framebuffer_remove(&ifbdev->fb->base);
	}
545 546

	kfree(ifbdev);
J
Jesse Barnes 已提交
547
}
548

549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
/*
 * 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 */
567
	for_each_crtc(dev, crtc) {
568 569
		struct drm_i915_gem_object *obj =
			intel_fb_obj(crtc->primary->state->fb);
570 571
		intel_crtc = to_intel_crtc(crtc);

572
		if (!crtc->state->active || !obj) {
573 574 575 576 577
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
				      pipe_name(intel_crtc->pipe));
			continue;
		}

578
		if (obj->base.size > max_size) {
579 580
			DRM_DEBUG_KMS("found possible fb from plane %c\n",
				      pipe_name(intel_crtc->pipe));
581 582
			fb = to_intel_framebuffer(crtc->primary->state->fb);
			max_size = obj->base.size;
583 584 585 586 587 588 589 590 591
		}
	}

	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 */
592
	for_each_crtc(dev, crtc) {
593 594 595 596
		unsigned int cur_size;

		intel_crtc = to_intel_crtc(crtc);

597
		if (!crtc->state->active) {
598 599 600 601 602 603 604 605 606 607
			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
608 609
		 * pipe.  Note we need to use the selected fb's pitch and bpp
		 * rather than the current pipe's, since they differ.
610
		 */
611
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
V
Ville Syrjälä 已提交
612
		cur_size = cur_size * fb->base.format->cpp[0];
613 614 615 616 617 618 619 620
		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;
		}

621
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
622
		cur_size = intel_fb_align_height(to_i915(dev), cur_size,
V
Ville Syrjälä 已提交
623
						 fb->base.format->format,
V
Ville Syrjälä 已提交
624
						 fb->base.modifier);
625 626 627
		cur_size *= fb->base.pitches[0];
		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
			      pipe_name(intel_crtc->pipe),
628 629
			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
V
Ville Syrjälä 已提交
630
			      fb->base.format->cpp[0] * 8,
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
			      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ä 已提交
651
	ifbdev->preferred_bpp = fb->base.format->cpp[0] * 8;
652 653
	ifbdev->fb = fb;

654
	drm_framebuffer_reference(&ifbdev->fb->base);
655 656

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

660
		if (!crtc->state->active)
661 662
			continue;

663
		WARN(!crtc->primary->fb,
664 665 666 667 668 669 670 671 672 673 674 675 676
		     "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;
}

677 678
static void intel_fbdev_suspend_worker(struct work_struct *work)
{
679 680 681
	intel_fbdev_set_suspend(&container_of(work,
					      struct drm_i915_private,
					      fbdev_suspend_work)->drm,
682 683 684 685
				FBINFO_STATE_RUNNING,
				true);
}

686 687
int intel_fbdev_init(struct drm_device *dev)
{
688
	struct drm_i915_private *dev_priv = to_i915(dev);
689
	struct intel_fbdev *ifbdev;
690
	int ret;
691

692
	if (WARN_ON(INTEL_INFO(dev_priv)->num_pipes == 0))
693 694 695 696
		return -ENODEV;

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

699 700
	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);

701 702
	if (!intel_fbdev_init_bios(dev, ifbdev))
		ifbdev->preferred_bpp = 32;
703

704
	ret = drm_fb_helper_init(dev, &ifbdev->helper, 4);
705 706 707 708
	if (ret) {
		kfree(ifbdev);
		return ret;
	}
709

710
	dev_priv->fbdev = ifbdev;
711 712
	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);

713
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
714

J
Jesse Barnes 已提交
715 716
	return 0;
}
717

718
static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
719
{
720
	struct intel_fbdev *ifbdev = data;
721 722

	/* Due to peculiar init order wrt to hpd handling this is separate. */
723 724
	if (drm_fb_helper_initial_config(&ifbdev->helper,
					 ifbdev->preferred_bpp))
725
		intel_fbdev_fini(ifbdev->helper.dev);
726 727
}

728 729
void intel_fbdev_initial_config_async(struct drm_device *dev)
{
730 731
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

732 733 734
	if (!ifbdev)
		return;

735 736 737 738 739 740 741 742 743 744 745
	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;
746 747
}

748 749
void intel_fbdev_fini(struct drm_device *dev)
{
750
	struct drm_i915_private *dev_priv = to_i915(dev);
751 752 753
	struct intel_fbdev *ifbdev = dev_priv->fbdev;

	if (!ifbdev)
754 755
		return;

756
	cancel_work_sync(&dev_priv->fbdev_suspend_work);
757
	if (!current_is_async())
758 759 760
		intel_fbdev_sync(ifbdev);

	intel_fbdev_destroy(ifbdev);
761 762
	dev_priv->fbdev = NULL;
}
763

764
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
765
{
766
	struct drm_i915_private *dev_priv = to_i915(dev);
767 768 769
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct fb_info *info;

770
	if (!ifbdev || !ifbdev->fb)
771 772
		return;

773 774
	info = ifbdev->helper.fbdev;

775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
	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;
		}
	}

802 803 804 805
	/* 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.
	 */
806
	if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
807 808
		memset_io(info->screen_base, 0, info->screen_size);

809
	drm_fb_helper_set_suspend(&ifbdev->helper, state);
810
	console_unlock();
811 812
}

813
void intel_fbdev_output_poll_changed(struct drm_device *dev)
814
{
815 816 817 818
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

	if (ifbdev && ifbdev->fb)
		drm_fb_helper_hotplug_event(&ifbdev->helper);
819
}
820

821
void intel_fbdev_restore_mode(struct drm_device *dev)
822
{
823
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
824

825
	if (!ifbdev)
B
Ben Widawsky 已提交
826 827
		return;

828
	intel_fbdev_sync(ifbdev);
829 830
	if (!ifbdev->fb)
		return;
831

832 833
	if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
		intel_fbdev_invalidate(ifbdev);
834
}