intel_fbdev.c 24.0 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 (IS_ERR(obj)) {
155
		DRM_ERROR("failed to allocate framebuffer\n");
156
		ret = PTR_ERR(obj);
J
Jesse Barnes 已提交
157 158 159
		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
	struct fb_info *info;
	struct drm_framebuffer *fb;
189
	struct i915_vma *vma;
190
	struct drm_i915_gem_object *obj;
191
	bool prealloc = false;
192 193
	void *vaddr;
	int ret;
194

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

	obj = intel_fb->obj;

220 221
	mutex_lock(&dev->struct_mutex);

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

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

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

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

241
	ifbdev->helper.fb = fb;
242

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

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

248 249
	vma = i915_gem_obj_to_ggtt(obj);

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

254 255
	info->fix.smem_start = dev->mode_config.fb_base + vma->node.start;
	info->fix.smem_len = vma->node.size;
J
Jesse Barnes 已提交
256

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

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

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

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

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

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

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

289 290
out_destroy_fbi:
	drm_fb_helper_release_fbi(helper);
291
out_unpin:
292
	intel_unpin_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
293
out_unlock:
J
Jesse Barnes 已提交
294 295 296 297
	mutex_unlock(&dev->struct_mutex);
	return ret;
}

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

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 359 360
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,
361
				    struct drm_fb_offset *offsets,
362 363
				    bool *enabled, int width, int height)
{
364
	struct drm_device *dev = fb_helper->dev;
365 366
	unsigned long conn_configured, mask;
	unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
367
	int i, j;
368
	bool *save_enabled;
369
	bool fallback = true;
370 371
	int num_connectors_enabled = 0;
	int num_connectors_detected = 0;
372
	int pass = 0;
373

374
	save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
375 376 377
	if (!save_enabled)
		return false;

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

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

392
		if (conn_configured & BIT(i))
393 394 395 396 397
			continue;

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

398 399 400
		if (connector->status == connector_status_connected)
			num_connectors_detected++;

401
		if (!enabled[i]) {
402
			DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
403
				      connector->name);
404
			conn_configured |= BIT(i);
405 406 407
			continue;
		}

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

415 416
		encoder = connector->state->best_encoder;
		if (!encoder || WARN_ON(!connector->state->crtc)) {
417 418 419
			if (connector->force > DRM_FORCE_OFF)
				goto bail;

420
			DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
421
				      connector->name);
422
			enabled[i] = false;
423
			conn_configured |= BIT(i);
424 425 426
			continue;
		}

427 428
		num_connectors_enabled++;

429 430 431 432 433 434 435
		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;
		}

436 437
		new_crtc = intel_fb_helper_crtc(fb_helper,
						connector->state->crtc);
438 439 440 441 442 443

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

451
		DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
452
			      connector->name);
453 454 455 456 457 458

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

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

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

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

495
		DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
496
			      connector->name,
497
			      connector->state->crtc->base.id,
498
			      connector->state->crtc->name,
499 500
			      modes[i]->hdisplay, modes[i]->vdisplay,
			      modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :"");
501

502
		fallback = false;
503
		conn_configured |= BIT(i);
504 505 506 507 508
	}

	if ((conn_configured & mask) != mask) {
		pass++;
		goto retry;
509 510
	}

511 512 513 514 515 516 517 518 519 520 521 522 523
	/*
	 * 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;
	}

524
	if (fallback) {
525
bail:
526
		DRM_DEBUG_KMS("Not using firmware configuration\n");
527
		memcpy(enabled, save_enabled, count);
528 529
		kfree(save_enabled);
		return false;
530 531
	}

532
	kfree(save_enabled);
533 534 535
	return true;
}

536
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
537
	.initial_config = intel_fb_initial_config,
538 539
	.gamma_set = intel_crtc_fb_gamma_set,
	.gamma_get = intel_crtc_fb_gamma_get,
540
	.fb_probe = intelfb_create,
541
};
J
Jesse Barnes 已提交
542

543
static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
J
Jesse Barnes 已提交
544
{
545 546 547 548
	/* 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.
	 */
549

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

553
	drm_fb_helper_fini(&ifbdev->helper);
J
Jesse Barnes 已提交
554

555
	if (ifbdev->fb) {
556
		mutex_lock(&ifbdev->helper.dev->struct_mutex);
557
		intel_unpin_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0));
558
		mutex_unlock(&ifbdev->helper.dev->struct_mutex);
559

560 561
		drm_framebuffer_remove(&ifbdev->fb->base);
	}
562 563

	kfree(ifbdev);
J
Jesse Barnes 已提交
564
}
565

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

589
		if (!crtc->state->active || !obj) {
590 591 592 593 594
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
				      pipe_name(intel_crtc->pipe));
			continue;
		}

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

	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 */
609
	for_each_crtc(dev, crtc) {
610 611 612 613
		unsigned int cur_size;

		intel_crtc = to_intel_crtc(crtc);

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

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

668
	ifbdev->preferred_bpp = fb->base.bits_per_pixel;
669 670
	ifbdev->fb = fb;

671
	drm_framebuffer_reference(&ifbdev->fb->base);
672 673

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

677
		if (!crtc->state->active)
678 679
			continue;

680
		WARN(!crtc->primary->fb,
681 682 683 684 685 686 687 688 689 690 691 692 693
		     "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;
}

694 695 696 697 698 699 700 701 702
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);
}

703 704
int intel_fbdev_init(struct drm_device *dev)
{
705
	struct intel_fbdev *ifbdev;
706
	struct drm_i915_private *dev_priv = to_i915(dev);
707
	int ret;
708

709 710 711 712 713
	if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0))
		return -ENODEV;

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

716 717
	drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);

718 719
	if (!intel_fbdev_init_bios(dev, ifbdev))
		ifbdev->preferred_bpp = 32;
720

721
	ret = drm_fb_helper_init(dev, &ifbdev->helper,
722
				 INTEL_INFO(dev)->num_pipes, 4);
723 724 725 726
	if (ret) {
		kfree(ifbdev);
		return ret;
	}
727

728
	dev_priv->fbdev = ifbdev;
729 730
	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);

731
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
732

J
Jesse Barnes 已提交
733 734
	return 0;
}
735

736
static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
737
{
738
	struct intel_fbdev *ifbdev = data;
739 740

	/* Due to peculiar init order wrt to hpd handling this is separate. */
741 742
	if (drm_fb_helper_initial_config(&ifbdev->helper,
					 ifbdev->preferred_bpp))
743
		intel_fbdev_fini(ifbdev->helper.dev);
744 745
}

746 747
void intel_fbdev_initial_config_async(struct drm_device *dev)
{
748 749 750 751 752 753 754 755 756 757 758 759 760
	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;
761 762
}

763 764
void intel_fbdev_fini(struct drm_device *dev)
{
765
	struct drm_i915_private *dev_priv = to_i915(dev);
766 767 768
	struct intel_fbdev *ifbdev = dev_priv->fbdev;

	if (!ifbdev)
769 770
		return;

771
	flush_work(&dev_priv->fbdev_suspend_work);
772
	if (!current_is_async())
773 774 775
		intel_fbdev_sync(ifbdev);

	intel_fbdev_destroy(ifbdev);
776 777
	dev_priv->fbdev = NULL;
}
778

779
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
780
{
781
	struct drm_i915_private *dev_priv = to_i915(dev);
782 783 784 785
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct fb_info *info;

	if (!ifbdev)
786 787
		return;

788 789
	info = ifbdev->helper.fbdev;

790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
	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;
		}
	}

817 818 819 820
	/* 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.
	 */
821
	if (state == FBINFO_STATE_RUNNING && ifbdev->fb->obj->stolen)
822 823
		memset_io(info->screen_base, 0, info->screen_size);

824
	drm_fb_helper_set_suspend(&ifbdev->helper, state);
825
	console_unlock();
826 827
}

828
void intel_fbdev_output_poll_changed(struct drm_device *dev)
829
{
830
	struct drm_i915_private *dev_priv = to_i915(dev);
831 832
	if (dev_priv->fbdev)
		drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
833
}
834

835
void intel_fbdev_restore_mode(struct drm_device *dev)
836 837
{
	int ret;
838
	struct drm_i915_private *dev_priv = to_i915(dev);
839 840
	struct intel_fbdev *ifbdev = dev_priv->fbdev;
	struct drm_fb_helper *fb_helper;
841

842
	if (!ifbdev)
B
Ben Widawsky 已提交
843 844
		return;

845 846
	intel_fbdev_sync(ifbdev);

847 848 849 850
	fb_helper = &ifbdev->helper;

	ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
	if (ret) {
851
		DRM_DEBUG("failed to restore crtc mode\n");
852 853 854 855 856
	} else {
		mutex_lock(&fb_helper->dev->struct_mutex);
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
		mutex_unlock(&fb_helper->dev->struct_mutex);
	}
857
}