intel_fbdev.c 23.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 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
	DRM_FB_HELPER_DEFAULT_OPS,
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,
J
Jesse Barnes 已提交
112 113
};

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

127
	/* we don't do packed 24bpp */
128 129
	if (sizes->surface_bpp == 24)
		sizes->surface_bpp = 32;
130

131 132
	mode_cmd.width = sizes->surface_width;
	mode_cmd.height = sizes->surface_height;
J
Jesse Barnes 已提交
133

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

139 140
	mutex_lock(&dev->struct_mutex);

141
	size = mode_cmd.pitches[0] * mode_cmd.height;
142
	size = PAGE_ALIGN(size);
143 144 145 146

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

157 158
	fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
	if (IS_ERR(fb)) {
159
		i915_gem_object_put(obj);
160
		ret = PTR_ERR(fb);
161
		goto out;
162 163
	}

164 165
	mutex_unlock(&dev->struct_mutex);

166
	ifbdev->fb = to_intel_framebuffer(fb);
167 168 169 170

	return 0;

out:
171
	mutex_unlock(&dev->struct_mutex);
172 173 174 175 176 177 178 179
	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);
180
	struct intel_framebuffer *intel_fb = ifbdev->fb;
181
	struct drm_device *dev = helper->dev;
182
	struct drm_i915_private *dev_priv = to_i915(dev);
D
David Weinehall 已提交
183
	struct pci_dev *pdev = dev_priv->drm.pdev;
184
	struct i915_ggtt *ggtt = &dev_priv->ggtt;
185 186
	struct fb_info *info;
	struct drm_framebuffer *fb;
187
	struct i915_vma *vma;
188
	bool prealloc = false;
189
	void __iomem *vaddr;
190
	int ret;
191

192 193 194 195 196 197 198 199 200 201
	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;
	}
202
	if (!intel_fb || WARN_ON(!intel_fb->obj)) {
203
		DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
204 205
		ret = intelfb_alloc(helper, sizes);
		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 212 213 214
		sizes->fb_width = intel_fb->base.width;
		sizes->fb_height = intel_fb->base.height;
	}

215 216
	mutex_lock(&dev->struct_mutex);

217 218 219 220
	/* 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 已提交
221 222 223
	vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
	if (IS_ERR(vma)) {
		ret = PTR_ERR(vma);
224
		goto out_unlock;
C
Chris Wilson 已提交
225
	}
226

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

234
	info->par = helper;
J
Jesse Barnes 已提交
235

236
	fb = &ifbdev->fb->base;
J
Jesse Barnes 已提交
237

238
	ifbdev->helper.fb = fb;
239

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

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

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

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

252 253
	vaddr = i915_vma_pin_iomap(vma);
	if (IS_ERR(vaddr)) {
254
		DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
255
		ret = PTR_ERR(vaddr);
256
		goto out_destroy_fbi;
J
Jesse Barnes 已提交
257
	}
258 259
	info->screen_base = vaddr;
	info->screen_size = vma->node.size;
J
Jesse Barnes 已提交
260

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

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

267 268 269 270
	/* 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 已提交
271
	if (intel_fb->obj->stolen && !prealloc)
272 273
		memset_io(info->screen_base, 0, info->screen_size);

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

276 277
	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
		      fb->width, fb->height, i915_ggtt_offset(vma));
C
Chris Wilson 已提交
278
	ifbdev->vma = vma;
J
Jesse Barnes 已提交
279 280

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

284 285
out_destroy_fbi:
	drm_fb_helper_release_fbi(helper);
286
out_unpin:
287
	intel_unpin_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
288
out_unlock:
J
Jesse Barnes 已提交
289 290 291 292
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

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

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 347 348 349 350 351 352 353 354 355
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,
356
				    struct drm_fb_offset *offsets,
357 358
				    bool *enabled, int width, int height)
{
359
	struct drm_i915_private *dev_priv = to_i915(fb_helper->dev);
360 361
	unsigned long conn_configured, mask;
	unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
362
	int i, j;
363
	bool *save_enabled;
364
	bool fallback = true;
365 366
	int num_connectors_enabled = 0;
	int num_connectors_detected = 0;
367
	int pass = 0;
368

369
	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
370 371 372
	if (!save_enabled)
		return false;

373 374 375
	memcpy(save_enabled, enabled, count);
	mask = BIT(count) - 1;
	conn_configured = 0;
376
retry:
377
	for (i = 0; i < count; i++) {
378 379 380 381
		struct drm_fb_helper_connector *fb_conn;
		struct drm_connector *connector;
		struct drm_encoder *encoder;
		struct drm_fb_helper_crtc *new_crtc;
382
		struct intel_crtc *intel_crtc;
383 384 385

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

387
		if (conn_configured & BIT(i))
388 389 390 391 392
			continue;

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

393 394 395
		if (connector->status == connector_status_connected)
			num_connectors_detected++;

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

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

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

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

422 423
		num_connectors_enabled++;

424 425 426 427 428 429 430
		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;
		}

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

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

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

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

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

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

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

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

497
		fallback = false;
498
		conn_configured |= BIT(i);
499 500 501 502 503
	}

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

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

519
	if (fallback) {
520
bail:
521
		DRM_DEBUG_KMS("Not using firmware configuration\n");
522
		memcpy(enabled, save_enabled, count);
523 524
		kfree(save_enabled);
		return false;
525 526
	}

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

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

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

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

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

550
	if (ifbdev->fb) {
551
		mutex_lock(&ifbdev->helper.dev->struct_mutex);
552
		intel_unpin_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
553
		mutex_unlock(&ifbdev->helper.dev->struct_mutex);
554

555 556
		drm_framebuffer_remove(&ifbdev->fb->base);
	}
557 558

	kfree(ifbdev);
J
Jesse Barnes 已提交
559
}
560

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

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

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

	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 */
604
	for_each_crtc(dev, crtc) {
605 606 607 608
		unsigned int cur_size;

		intel_crtc = to_intel_crtc(crtc);

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

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

663
	ifbdev->preferred_bpp = fb->base.bits_per_pixel;
664 665
	ifbdev->fb = fb;

666
	drm_framebuffer_reference(&ifbdev->fb->base);
667 668

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

672
		if (!crtc->state->active)
673 674
			continue;

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

689 690
static void intel_fbdev_suspend_worker(struct work_struct *work)
{
691 692 693
	intel_fbdev_set_suspend(&container_of(work,
					      struct drm_i915_private,
					      fbdev_suspend_work)->drm,
694 695 696 697
				FBINFO_STATE_RUNNING,
				true);
}

698 699
int intel_fbdev_init(struct drm_device *dev)
{
700
	struct drm_i915_private *dev_priv = to_i915(dev);
701
	struct intel_fbdev *ifbdev;
702
	int ret;
703

704
	if (WARN_ON(INTEL_INFO(dev_priv)->num_pipes == 0))
705 706 707 708
		return -ENODEV;

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

711 712
	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);

713 714
	if (!intel_fbdev_init_bios(dev, ifbdev))
		ifbdev->preferred_bpp = 32;
715

716
	ret = drm_fb_helper_init(dev, &ifbdev->helper,
717
				 INTEL_INFO(dev_priv)->num_pipes, 4);
718 719 720 721
	if (ret) {
		kfree(ifbdev);
		return ret;
	}
722

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

726
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
727

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

731
static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
732
{
733
	struct intel_fbdev *ifbdev = data;
734 735

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

741 742
void intel_fbdev_initial_config_async(struct drm_device *dev)
{
743 744 745 746 747 748 749 750 751 752 753 754 755
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

	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;
756 757
}

758 759
void intel_fbdev_fini(struct drm_device *dev)
{
760
	struct drm_i915_private *dev_priv = to_i915(dev);
761 762 763
	struct intel_fbdev *ifbdev = dev_priv->fbdev;

	if (!ifbdev)
764 765
		return;

766
	cancel_work_sync(&dev_priv->fbdev_suspend_work);
767
	if (!current_is_async())
768 769 770
		intel_fbdev_sync(ifbdev);

	intel_fbdev_destroy(ifbdev);
771 772
	dev_priv->fbdev = NULL;
}
773

774
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
775
{
776
	struct drm_i915_private *dev_priv = to_i915(dev);
777 778 779
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct fb_info *info;

780
	if (!ifbdev || !ifbdev->fb)
781 782
		return;

783 784
	info = ifbdev->helper.fbdev;

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
	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;
		}
	}

812 813 814 815
	/* 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.
	 */
816
	if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
817 818
		memset_io(info->screen_base, 0, info->screen_size);

819
	drm_fb_helper_set_suspend(&ifbdev->helper, state);
820
	console_unlock();
821 822
}

823
void intel_fbdev_output_poll_changed(struct drm_device *dev)
824
{
825 826 827 828
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;

	if (ifbdev && ifbdev->fb)
		drm_fb_helper_hotplug_event(&ifbdev->helper);
829
}
830

831
void intel_fbdev_restore_mode(struct drm_device *dev)
832
{
833
	struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
834

835
	if (!ifbdev)
B
Ben Widawsky 已提交
836 837
		return;

838
	intel_fbdev_sync(ifbdev);
839 840
	if (!ifbdev->fb)
		return;
841

842
	if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper)) {
843
		DRM_DEBUG("failed to restore crtc mode\n");
844
	} else {
845
		mutex_lock(&dev->struct_mutex);
846
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
847
		mutex_unlock(&dev->struct_mutex);
848
	}
849
}