intel_fbdev.c 23.7 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 38
#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/fb.h>
#include <linux/init.h>
39
#include <linux/vga_switcheroo.h>
J
Jesse Barnes 已提交
40

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

48 49 50 51 52 53 54 55 56 57 58
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);

	if (ret == 0) {
		mutex_lock(&fb_helper->dev->struct_mutex);
59
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
60 61 62 63 64 65
		mutex_unlock(&fb_helper->dev->struct_mutex);
	}

	return ret;
}

66 67 68 69 70 71 72 73 74 75 76
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);

	if (ret == 0) {
		mutex_lock(&fb_helper->dev->struct_mutex);
77
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
78 79 80 81 82 83
		mutex_unlock(&fb_helper->dev->struct_mutex);
	}

	return ret;
}

84 85 86 87 88 89 90 91 92 93 94 95
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;
	ret = drm_fb_helper_pan_display(var, info);

	if (ret == 0) {
		mutex_lock(&fb_helper->dev->struct_mutex);
96
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
97 98 99 100 101 102
		mutex_unlock(&fb_helper->dev->struct_mutex);
	}

	return ret;
}

J
Jesse Barnes 已提交
103 104
static struct fb_ops intelfb_ops = {
	.owner = THIS_MODULE,
105
	.fb_check_var = drm_fb_helper_check_var,
106
	.fb_set_par = intel_fbdev_set_par,
107 108 109
	.fb_fillrect = drm_fb_helper_cfb_fillrect,
	.fb_copyarea = drm_fb_helper_cfb_copyarea,
	.fb_imageblit = drm_fb_helper_cfb_imageblit,
110
	.fb_pan_display = intel_fbdev_pan_display,
111
	.fb_blank = intel_fbdev_blank,
112
	.fb_setcmap = drm_fb_helper_setcmap,
J
Jesse Barnes 已提交
113 114
	.fb_debug_enter = drm_fb_helper_debug_enter,
	.fb_debug_leave = drm_fb_helper_debug_leave,
J
Jesse Barnes 已提交
115 116
};

117 118
static int intelfb_alloc(struct drm_fb_helper *helper,
			 struct drm_fb_helper_surface_size *sizes)
J
Jesse Barnes 已提交
119
{
120 121
	struct intel_fbdev *ifbdev =
		container_of(helper, struct intel_fbdev, helper);
122
	struct drm_framebuffer *fb;
123
	struct drm_device *dev = helper->dev;
124
	struct drm_i915_private *dev_priv = to_i915(dev);
125
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
126
	struct drm_mode_fb_cmd2 mode_cmd = {};
127
	struct drm_i915_gem_object *obj = NULL;
128
	int size, ret;
J
Jesse Barnes 已提交
129

130
	/* we don't do packed 24bpp */
131 132
	if (sizes->surface_bpp == 24)
		sizes->surface_bpp = 32;
133

134 135
	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
J
Jesse Barnes 已提交
136

137 138
	mode_cmd.pitches[0] = ALIGN(mode_cmd.width *
				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
139 140
	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
							  sizes->surface_depth);
J
Jesse Barnes 已提交
141

142 143
	mutex_lock(&dev->struct_mutex);

144
	size = mode_cmd.pitches[0] * mode_cmd.height;
145
	size = PAGE_ALIGN(size);
146 147 148 149

	/* 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. */
150
	if (size * 2 < ggtt->stolen_usable_size)
151
		obj = i915_gem_object_create_stolen(dev, size);
152
	if (obj == NULL)
153
		obj = i915_gem_object_create(dev, size);
154
	if (!obj) {
155
		DRM_ERROR("failed to allocate framebuffer\n");
J
Jesse Barnes 已提交
156 157 158 159
		ret = -ENOMEM;
		goto out;
	}

160 161
	fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
	if (IS_ERR(fb)) {
162
		drm_gem_object_unreference(&obj->base);
163
		ret = PTR_ERR(fb);
164
		goto out;
165 166
	}

167 168
	mutex_unlock(&dev->struct_mutex);

169
	ifbdev->fb = to_intel_framebuffer(fb);
170 171 172 173

	return 0;

out:
174
	mutex_unlock(&dev->struct_mutex);
175 176 177 178 179 180 181 182
	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);
183
	struct intel_framebuffer *intel_fb = ifbdev->fb;
184
	struct drm_device *dev = helper->dev;
185 186
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
187 188 189 190
	struct fb_info *info;
	struct drm_framebuffer *fb;
	struct drm_i915_gem_object *obj;
	int size, ret;
191
	bool prealloc = false;
192

193 194 195 196 197 198 199 200 201 202
	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;
	}
203
	if (!intel_fb || WARN_ON(!intel_fb->obj)) {
204
		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
205 206
		ret = intelfb_alloc(helper, sizes);
		if (ret)
207
			return ret;
208
		intel_fb = ifbdev->fb;
209
	} else {
210
		DRM_DEBUG_KMS("re-using BIOS fb\n");
211
		prealloc = true;
212 213 214 215 216 217 218
		sizes->fb_width = intel_fb->base.width;
		sizes->fb_height = intel_fb->base.height;
	}

	obj = intel_fb->obj;
	size = obj->base.size;

219 220
	mutex_lock(&dev->struct_mutex);

221 222 223 224
	/* 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.
	 */
225
	ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
226 227 228
	if (ret)
		goto out_unlock;

229 230
	info = drm_fb_helper_alloc_fbi(helper);
	if (IS_ERR(info)) {
231
		DRM_ERROR("Failed to allocate fb_info\n");
232
		ret = PTR_ERR(info);
233
		goto out_unpin;
J
Jesse Barnes 已提交
234 235
	}

236
	info->par = helper;
J
Jesse Barnes 已提交
237

238
	fb = &ifbdev->fb->base;
J
Jesse Barnes 已提交
239

240
	ifbdev->helper.fb = fb;
241

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

244
	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
J
Jesse Barnes 已提交
245 246
	info->fbops = &intelfb_ops;

247
	/* setup aperture base/size for vesafb takeover */
248
	info->apertures->ranges[0].base = dev->mode_config.fb_base;
249
	info->apertures->ranges[0].size = ggtt->mappable_end;
250

251
	info->fix.smem_start = dev->mode_config.fb_base + i915_gem_obj_ggtt_offset(obj);
J
Jesse Barnes 已提交
252 253
	info->fix.smem_len = size;

254
	info->screen_base =
255
		ioremap_wc(ggtt->mappable_base + i915_gem_obj_ggtt_offset(obj),
256
			   size);
J
Jesse Barnes 已提交
257
	if (!info->screen_base) {
258
		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
J
Jesse Barnes 已提交
259
		ret = -ENOSPC;
260
		goto out_destroy_fbi;
J
Jesse Barnes 已提交
261 262 263
	}
	info->screen_size = size;

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

267
	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
268
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
J
Jesse Barnes 已提交
269

270 271 272 273
	/* 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.
	 */
274
	if (ifbdev->fb->obj->stolen && !prealloc)
275 276
		memset_io(info->screen_base, 0, info->screen_size);

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

279
	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
280
		      fb->width, fb->height,
281
		      i915_gem_obj_ggtt_offset(obj), obj);
J
Jesse Barnes 已提交
282 283

	mutex_unlock(&dev->struct_mutex);
284
	vga_switcheroo_client_fb_set(dev->pdev, info);
J
Jesse Barnes 已提交
285 286
	return 0;

287 288
out_destroy_fbi:
	drm_fb_helper_release_fbi(helper);
289
out_unpin:
B
Ben Widawsky 已提交
290
	i915_gem_object_ggtt_unpin(obj);
291
out_unlock:
J
Jesse Barnes 已提交
292 293 294 295
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
/** 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;
}

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 347 348 349 350 351 352 353 354 355 356 357 358
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,
359
				    struct drm_fb_offset *offsets,
360 361
				    bool *enabled, int width, int height)
{
362
	struct drm_device *dev = fb_helper->dev;
363
	int i, j;
364
	bool *save_enabled;
365
	bool fallback = true;
366 367
	int num_connectors_enabled = 0;
	int num_connectors_detected = 0;
368 369
	uint64_t conn_configured = 0, mask;
	int pass = 0;
370 371 372 373 374 375 376

	save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
			       GFP_KERNEL);
	if (!save_enabled)
		return false;

	memcpy(save_enabled, enabled, dev->mode_config.num_connector);
377 378
	mask = (1 << fb_helper->connector_count) - 1;
retry:
379 380 381 382 383
	for (i = 0; i < fb_helper->connector_count; i++) {
		struct drm_fb_helper_connector *fb_conn;
		struct drm_connector *connector;
		struct drm_encoder *encoder;
		struct drm_fb_helper_crtc *new_crtc;
384
		struct intel_crtc *intel_crtc;
385 386 387

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

389 390 391 392 393 394
		if (conn_configured & (1 << i))
			continue;

		if (pass == 0 && !connector->has_tile)
			continue;

395 396 397
		if (connector->status == connector_status_connected)
			num_connectors_detected++;

398
		if (!enabled[i]) {
399
			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
400
				      connector->name);
401
			conn_configured |= (1 << i);
402 403 404
			continue;
		}

405 406 407 408 409 410 411
		if (connector->force == DRM_FORCE_OFF) {
			DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
				      connector->name);
			enabled[i] = false;
			continue;
		}

412 413
		encoder = connector->state->best_encoder;
		if (!encoder || WARN_ON(!connector->state->crtc)) {
414 415 416
			if (connector->force > DRM_FORCE_OFF)
				goto bail;

417
			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
418
				      connector->name);
419
			enabled[i] = false;
420
			conn_configured |= (1 << i);
421 422 423
			continue;
		}

424 425
		num_connectors_enabled++;

426 427 428 429 430 431 432
		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;
		}

433
		new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc);
434 435 436 437 438 439 440

		/*
		 * Make sure we're not trying to drive multiple connectors
		 * with a single CRTC, since our cloning support may not
		 * match the BIOS.
		 */
		for (j = 0; j < fb_helper->connector_count; j++) {
441
			if (crtcs[j] == new_crtc) {
442
				DRM_DEBUG_KMS("fallback: cloned configuration\n");
443
				goto bail;
444
			}
445 446
		}

447
		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
448
			      connector->name);
449 450 451 452 453 454

		/* go for command line mode first */
		modes[i] = drm_pick_cmdline_mode(fb_conn, width, height);

		/* try for preferred next */
		if (!modes[i]) {
455 456
			DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
				      connector->name, connector->has_tile);
457 458 459 460
			modes[i] = drm_has_preferred_mode(fb_conn, width,
							  height);
		}

461 462 463
		/* 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",
464
				      connector->name);
465 466 467 468 469
			modes[i] = list_first_entry(&connector->modes,
						    struct drm_display_mode,
						    head);
		}

470 471 472 473 474 475
		/* 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
476
			 * usually contains. But since our current
477
			 * code puts a mode derived from the post-pfit timings
478
			 * into crtc->mode this works out correctly.
479 480 481 482 483
			 *
			 * 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.
484
			 */
485
			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
486
				      connector->name);
487
			modes[i] = &connector->state->crtc->mode;
488 489 490
		}
		crtcs[i] = new_crtc;

491
		DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
492
			      connector->name,
493 494
			      pipe_name(to_intel_crtc(connector->state->crtc)->pipe),
			      connector->state->crtc->base.id,
495 496
			      modes[i]->hdisplay, modes[i]->vdisplay,
			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
497

498
		fallback = false;
499 500 501 502 503 504
		conn_configured |= (1 << i);
	}

	if ((conn_configured & mask) != mask) {
		pass++;
		goto retry;
505 506
	}

507 508 509 510 511 512 513 514 515 516 517 518 519
	/*
	 * 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 &&
	    num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
		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;
	}

520
	if (fallback) {
521
bail:
522
		DRM_DEBUG_KMS("Not using firmware configuration\n");
523 524 525
		memcpy(enabled, save_enabled, dev->mode_config.num_connector);
		kfree(save_enabled);
		return false;
526 527
	}

528
	kfree(save_enabled);
529 530 531
	return true;
}

532
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
533
	.initial_config = intel_fb_initial_config,
534 535
	.gamma_set = intel_crtc_fb_gamma_set,
	.gamma_get = intel_crtc_fb_gamma_get,
536
	.fb_probe = intelfb_create,
537
};
J
Jesse Barnes 已提交
538

539 540
static void intel_fbdev_destroy(struct drm_device *dev,
				struct intel_fbdev *ifbdev)
J
Jesse Barnes 已提交
541
{
542 543 544 545
	/* 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.
	 */
546

547 548
	drm_fb_helper_unregister_fbi(&ifbdev->helper);
	drm_fb_helper_release_fbi(&ifbdev->helper);
J
Jesse Barnes 已提交
549

550
	drm_fb_helper_fini(&ifbdev->helper);
J
Jesse Barnes 已提交
551

552 553 554 555
	if (ifbdev->fb) {
		drm_framebuffer_unregister_private(&ifbdev->fb->base);
		drm_framebuffer_remove(&ifbdev->fb->base);
	}
J
Jesse Barnes 已提交
556
}
557

558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
/*
 * 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 */
576
	for_each_crtc(dev, crtc) {
577 578
		struct drm_i915_gem_object *obj =
			intel_fb_obj(crtc->primary->state->fb);
579 580
		intel_crtc = to_intel_crtc(crtc);

581
		if (!crtc->state->active || !obj) {
582 583 584 585 586
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
				      pipe_name(intel_crtc->pipe));
			continue;
		}

587
		if (obj->base.size > max_size) {
588 589
			DRM_DEBUG_KMS("found possible fb from plane %c\n",
				      pipe_name(intel_crtc->pipe));
590 591
			fb = to_intel_framebuffer(crtc->primary->state->fb);
			max_size = obj->base.size;
592 593 594 595 596 597 598 599 600
		}
	}

	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 */
601
	for_each_crtc(dev, crtc) {
602 603 604 605
		unsigned int cur_size;

		intel_crtc = to_intel_crtc(crtc);

606
		if (!crtc->state->active) {
607 608 609 610 611 612 613 614 615 616
			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
617 618
		 * pipe.  Note we need to use the selected fb's pitch and bpp
		 * rather than the current pipe's, since they differ.
619
		 */
620
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
621 622 623 624 625 626 627 628 629
		cur_size = cur_size * fb->base.bits_per_pixel / 8;
		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;
		}

630
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
631
		cur_size = intel_fb_align_height(dev, cur_size,
632 633
						 fb->base.pixel_format,
						 fb->base.modifier[0]);
634 635 636
		cur_size *= fb->base.pitches[0];
		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
			      pipe_name(intel_crtc->pipe),
637 638
			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
639
			      fb->base.bits_per_pixel,
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
			      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;
	}

660
	ifbdev->preferred_bpp = fb->base.bits_per_pixel;
661 662
	ifbdev->fb = fb;

663
	drm_framebuffer_reference(&ifbdev->fb->base);
664 665

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

669
		if (!crtc->state->active)
670 671
			continue;

672
		WARN(!crtc->primary->fb,
673 674 675 676 677 678 679 680 681 682 683 684 685
		     "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;
}

686 687 688 689 690 691 692 693 694
static void intel_fbdev_suspend_worker(struct work_struct *work)
{
	intel_fbdev_set_suspend(container_of(work,
					     struct drm_i915_private,
					     fbdev_suspend_work)->dev,
				FBINFO_STATE_RUNNING,
				true);
}

695 696
int intel_fbdev_init(struct drm_device *dev)
{
697
	struct intel_fbdev *ifbdev;
698
	struct drm_i915_private *dev_priv = dev->dev_private;
699
	int ret;
700

701 702 703 704 705
	if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
		return -ENODEV;

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

708 709
	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);

710 711
	if (!intel_fbdev_init_bios(dev, ifbdev))
		ifbdev->preferred_bpp = 32;
712

713
	ret = drm_fb_helper_init(dev, &ifbdev->helper,
714
				 INTEL_INFO(dev)->num_pipes, 4);
715 716 717 718
	if (ret) {
		kfree(ifbdev);
		return ret;
	}
719

R
Rob Clark 已提交
720 721
	ifbdev->helper.atomic = true;

722
	dev_priv->fbdev = ifbdev;
723 724
	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);

725
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
726

J
Jesse Barnes 已提交
727 728
	return 0;
}
729

730
static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
731
{
732
	struct drm_i915_private *dev_priv = data;
733
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
734 735

	/* Due to peculiar init order wrt to hpd handling this is separate. */
736 737 738
	if (drm_fb_helper_initial_config(&ifbdev->helper,
					 ifbdev->preferred_bpp))
		intel_fbdev_fini(dev_priv->dev);
739 740
}

741 742 743 744 745
void intel_fbdev_initial_config_async(struct drm_device *dev)
{
	async_schedule(intel_fbdev_initial_config, to_i915(dev));
}

746 747
void intel_fbdev_fini(struct drm_device *dev)
{
748
	struct drm_i915_private *dev_priv = dev->dev_private;
749 750 751
	if (!dev_priv->fbdev)
		return;

752 753
	flush_work(&dev_priv->fbdev_suspend_work);

754 755
	if (!current_is_async())
		async_synchronize_full();
756
	intel_fbdev_destroy(dev, dev_priv->fbdev);
757
	kfree(dev_priv->fbdev);
758 759
	dev_priv->fbdev = NULL;
}
760

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

	if (!ifbdev)
768 769
		return;

770 771
	info = ifbdev->helper.fbdev;

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

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

806
	drm_fb_helper_set_suspend(&ifbdev->helper, state);
807
	console_unlock();
808 809
}

810
void intel_fbdev_output_poll_changed(struct drm_device *dev)
811
{
812
	struct drm_i915_private *dev_priv = dev->dev_private;
813 814
	if (dev_priv->fbdev)
		drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
815
}
816

817
void intel_fbdev_restore_mode(struct drm_device *dev)
818 819
{
	int ret;
820
	struct drm_i915_private *dev_priv = dev->dev_private;
821 822
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct drm_fb_helper *fb_helper;
823

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

827 828 829 830
	fb_helper = &ifbdev->helper;

	ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
	if (ret) {
831
		DRM_DEBUG("failed to restore crtc mode\n");
832 833 834 835 836
	} else {
		mutex_lock(&fb_helper->dev->struct_mutex);
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
		mutex_unlock(&fb_helper->dev->struct_mutex);
	}
837
}