intel_fbc.c 47.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * Copyright © 2014 Intel Corporation
 *
 * 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.
 */

R
Rodrigo Vivi 已提交
24 25 26 27 28 29
/**
 * DOC: Frame Buffer Compression (FBC)
 *
 * FBC tries to save memory bandwidth (and so power consumption) by
 * compressing the amount of memory used by the display. It is total
 * transparent to user space and completely handled in the kernel.
30 31
 *
 * The benefits of FBC are mostly visible with solid backgrounds and
R
Rodrigo Vivi 已提交
32 33
 * variation-less patterns. It comes from keeping the memory footprint small
 * and having fewer memory pages opened and accessed for refreshing the display.
34
 *
R
Rodrigo Vivi 已提交
35 36 37 38
 * i915 is responsible to reserve stolen memory for FBC and configure its
 * offset on proper registers. The hardware takes care of all
 * compress/decompress. However there are many known cases where we have to
 * forcibly disable it to allow proper screen updates.
39 40
 */

41 42
#include <drm/drm_fourcc.h>

R
Rodrigo Vivi 已提交
43
#include "i915_drv.h"
44
#include "i915_vgpu.h"
45
#include "intel_cdclk.h"
46
#include "intel_de.h"
47
#include "intel_display_trace.h"
48
#include "intel_display_types.h"
49
#include "intel_fbc.h"
50
#include "intel_frontbuffer.h"
R
Rodrigo Vivi 已提交
51

52
struct intel_fbc_funcs {
53 54 55 56 57 58 59
	void (*activate)(struct intel_fbc *fbc);
	void (*deactivate)(struct intel_fbc *fbc);
	bool (*is_active)(struct intel_fbc *fbc);
	bool (*is_compressing)(struct intel_fbc *fbc);
	void (*nuke)(struct intel_fbc *fbc);
	void (*program_cfb)(struct intel_fbc *fbc);
	void (*set_false_color)(struct intel_fbc *fbc, bool enable);
60 61
};

62
struct intel_fbc_state {
63
	struct intel_plane *plane;
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	unsigned int cfb_stride;
	unsigned int cfb_size;
	unsigned int fence_y_offset;
	u16 override_cfb_stride;
	u16 interval;
	s8 fence_id;
};

struct intel_fbc {
	struct drm_i915_private *i915;
	const struct intel_fbc_funcs *funcs;

	/*
	 * This is always the inner lock when overlapping with
	 * struct_mutex and it's the outer lock when overlapping
	 * with stolen_lock.
	 */
	struct mutex lock;
	unsigned int possible_framebuffer_bits;
	unsigned int busy_bits;

	struct drm_mm_node compressed_fb;
	struct drm_mm_node compressed_llb;

	u8 limit;

	bool false_color;

	bool active;
	bool activated;
	bool flip_pending;

	bool underrun_detected;
	struct work_struct underrun_work;

	/*
	 * This structure contains everything that's relevant to program the
	 * hardware registers. When we want to figure out if we need to disable
	 * and re-enable FBC for a new configuration we just check if there's
	 * something different in the struct. The genx_fbc_activate functions
	 * are supposed to read from it in order to program the registers.
	 */
V
Ville Syrjälä 已提交
106
	struct intel_fbc_state state;
107 108
	const char *no_fbc_reason;
};
109

110 111
/* plane stride in pixels */
static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state)
112
{
113 114 115
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	unsigned int stride;

116
	stride = plane_state->view.color_plane[0].mapping_stride;
117 118 119 120 121 122 123
	if (!drm_rotation_90_or_270(plane_state->hw.rotation))
		stride /= fb->format->cpp[0];

	return stride;
}

/* plane stride based cfb stride in bytes, assuming 1:1 compression limit */
124
static unsigned int _intel_fbc_cfb_stride(const struct intel_plane_state *plane_state)
125 126 127
{
	unsigned int cpp = 4; /* FBC always 4 bytes per pixel */

128
	return intel_fbc_plane_stride(plane_state) * cpp;
129 130 131
}

/* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */
132
static unsigned int skl_fbc_min_cfb_stride(const struct intel_plane_state *plane_state)
133
{
134
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
135 136
	unsigned int limit = 4; /* 1:4 compression limit is the worst case */
	unsigned int cpp = 4; /* FBC always 4 bytes per pixel */
137
	unsigned int width = drm_rect_width(&plane_state->uapi.src) >> 16;
138 139 140 141
	unsigned int height = 4; /* FBC segment is 4 lines */
	unsigned int stride;

	/* minimum segment stride we can use */
142
	stride = width * cpp * height / limit;
143

144 145 146 147 148 149 150
	/*
	 * Wa_16011863758: icl+
	 * Avoid some hardware segment address miscalculation.
	 */
	if (DISPLAY_VER(i915) >= 11)
		stride += 64;

151 152 153 154 155 156 157 158 159 160 161
	/*
	 * At least some of the platforms require each 4 line segment to
	 * be 512 byte aligned. Just do it always for simplicity.
	 */
	stride = ALIGN(stride, 512);

	/* convert back to single line equivalent with 1:1 compression limit */
	return stride * limit / height;
}

/* properly aligned cfb stride in bytes, assuming 1:1 compression limit */
162
static unsigned int intel_fbc_cfb_stride(const struct intel_plane_state *plane_state)
163
{
164 165
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	unsigned int stride = _intel_fbc_cfb_stride(plane_state);
166 167 168 169 170 171

	/*
	 * At least some of the platforms require each 4 line segment to
	 * be 512 byte aligned. Aligning each line to 512 bytes guarantees
	 * that regardless of the compression limit we choose later.
	 */
172
	if (DISPLAY_VER(i915) >= 9)
173
		return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(plane_state));
174 175 176 177
	else
		return stride;
}

178
static unsigned int intel_fbc_cfb_size(const struct intel_plane_state *plane_state)
179
{
180 181
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	int lines = drm_rect_height(&plane_state->uapi.src) >> 16;
182

V
Ville Syrjälä 已提交
183
	if (DISPLAY_VER(i915) == 7)
184
		lines = min(lines, 2048);
V
Ville Syrjälä 已提交
185
	else if (DISPLAY_VER(i915) >= 8)
186
		lines = min(lines, 2560);
187

188
	return lines * intel_fbc_cfb_stride(plane_state);
189 190
}

191
static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_state)
192
{
193 194 195 196
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	unsigned int stride_aligned = intel_fbc_cfb_stride(plane_state);
	unsigned int stride = _intel_fbc_cfb_stride(plane_state);
	const struct drm_framebuffer *fb = plane_state->hw.fb;
197 198 199 200 201 202 203 204 205

	/*
	 * Override stride in 64 byte units per 4 line segment.
	 *
	 * Gen9 hw miscalculates cfb stride for linear as
	 * PLANE_STRIDE*512 instead of PLANE_STRIDE*64, so
	 * we always need to use the override there.
	 */
	if (stride != stride_aligned ||
206
	    (DISPLAY_VER(i915) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR))
207 208 209
		return stride_aligned * 4 / 64;

	return 0;
210 211
}

212
static u32 i8xx_fbc_ctl(struct intel_fbc *fbc)
213
{
V
Ville Syrjälä 已提交
214
	const struct intel_fbc_state *fbc_state = &fbc->state;
215
	struct drm_i915_private *i915 = fbc->i915;
216 217 218
	unsigned int cfb_stride;
	u32 fbc_ctl;

V
Ville Syrjälä 已提交
219
	cfb_stride = fbc_state->cfb_stride / fbc->limit;
220 221 222 223 224 225 226 227

	/* FBC_CTL wants 32B or 64B units */
	if (DISPLAY_VER(i915) == 2)
		cfb_stride = (cfb_stride / 32) - 1;
	else
		cfb_stride = (cfb_stride / 64) - 1;

	fbc_ctl = FBC_CTL_PERIODIC |
V
Ville Syrjälä 已提交
228
		FBC_CTL_INTERVAL(fbc_state->interval) |
229 230 231 232 233
		FBC_CTL_STRIDE(cfb_stride);

	if (IS_I945GM(i915))
		fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */

V
Ville Syrjälä 已提交
234 235
	if (fbc_state->fence_id >= 0)
		fbc_ctl |= FBC_CTL_FENCENO(fbc_state->fence_id);
236 237 238 239

	return fbc_ctl;
}

240
static u32 i965_fbc_ctl2(struct intel_fbc *fbc)
241
{
V
Ville Syrjälä 已提交
242
	const struct intel_fbc_state *fbc_state = &fbc->state;
243 244 245
	u32 fbc_ctl2;

	fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM |
V
Ville Syrjälä 已提交
246
		FBC_CTL_PLANE(fbc_state->plane->i9xx_plane);
247

V
Ville Syrjälä 已提交
248
	if (fbc_state->fence_id >= 0)
249
		fbc_ctl2 |= FBC_CTL_CPU_FENCE_EN;
250 251 252 253

	return fbc_ctl2;
}

254
static void i8xx_fbc_deactivate(struct intel_fbc *fbc)
255
{
256
	struct drm_i915_private *i915 = fbc->i915;
257 258 259
	u32 fbc_ctl;

	/* Disable compression */
V
Ville Syrjälä 已提交
260
	fbc_ctl = intel_de_read(i915, FBC_CONTROL);
261 262 263 264
	if ((fbc_ctl & FBC_CTL_EN) == 0)
		return;

	fbc_ctl &= ~FBC_CTL_EN;
V
Ville Syrjälä 已提交
265
	intel_de_write(i915, FBC_CONTROL, fbc_ctl);
266 267

	/* Wait for compressing bit to clear */
V
Ville Syrjälä 已提交
268
	if (intel_de_wait_for_clear(i915, FBC_STATUS,
269
				    FBC_STAT_COMPRESSING, 10)) {
V
Ville Syrjälä 已提交
270
		drm_dbg_kms(&i915->drm, "FBC idle timed out\n");
271 272 273 274
		return;
	}
}

275
static void i8xx_fbc_activate(struct intel_fbc *fbc)
276
{
V
Ville Syrjälä 已提交
277
	const struct intel_fbc_state *fbc_state = &fbc->state;
278
	struct drm_i915_private *i915 = fbc->i915;
279 280 281 282
	int i;

	/* Clear old tags */
	for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
V
Ville Syrjälä 已提交
283
		intel_de_write(i915, FBC_TAG(i), 0);
284

V
Ville Syrjälä 已提交
285 286
	if (DISPLAY_VER(i915) == 4) {
		intel_de_write(i915, FBC_CONTROL2,
287
			       i965_fbc_ctl2(fbc));
V
Ville Syrjälä 已提交
288
		intel_de_write(i915, FBC_FENCE_OFF,
V
Ville Syrjälä 已提交
289
			       fbc_state->fence_y_offset);
290 291
	}

V
Ville Syrjälä 已提交
292
	intel_de_write(i915, FBC_CONTROL,
293
		       FBC_CTL_EN | i8xx_fbc_ctl(fbc));
294 295
}

296
static bool i8xx_fbc_is_active(struct intel_fbc *fbc)
297
{
298
	return intel_de_read(fbc->i915, FBC_CONTROL) & FBC_CTL_EN;
299 300
}

301
static bool i8xx_fbc_is_compressing(struct intel_fbc *fbc)
302
{
303
	return intel_de_read(fbc->i915, FBC_STATUS) &
304 305 306
		(FBC_STAT_COMPRESSING | FBC_STAT_COMPRESSED);
}

307
static void i8xx_fbc_nuke(struct intel_fbc *fbc)
308
{
V
Ville Syrjälä 已提交
309 310
	struct intel_fbc_state *fbc_state = &fbc->state;
	enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
311
	struct drm_i915_private *dev_priv = fbc->i915;
312 313 314 315 316 317 318

	spin_lock_irq(&dev_priv->uncore.lock);
	intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
			  intel_de_read_fw(dev_priv, DSPADDR(i9xx_plane)));
	spin_unlock_irq(&dev_priv->uncore.lock);
}

319
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
320
{
321
	struct drm_i915_private *i915 = fbc->i915;
322 323 324 325 326 327 328 329 330 331 332 333

	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
					 fbc->compressed_fb.start, U32_MAX));
	GEM_BUG_ON(range_overflows_end_t(u64, i915->dsm.start,
					 fbc->compressed_llb.start, U32_MAX));

	intel_de_write(i915, FBC_CFB_BASE,
		       i915->dsm.start + fbc->compressed_fb.start);
	intel_de_write(i915, FBC_LL_BASE,
		       i915->dsm.start + fbc->compressed_llb.start);
}

334 335 336 337 338
static const struct intel_fbc_funcs i8xx_fbc_funcs = {
	.activate = i8xx_fbc_activate,
	.deactivate = i8xx_fbc_deactivate,
	.is_active = i8xx_fbc_is_active,
	.is_compressing = i8xx_fbc_is_compressing,
339
	.nuke = i8xx_fbc_nuke,
340
	.program_cfb = i8xx_fbc_program_cfb,
341 342
};

343
static void i965_fbc_nuke(struct intel_fbc *fbc)
344
{
V
Ville Syrjälä 已提交
345 346
	struct intel_fbc_state *fbc_state = &fbc->state;
	enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
347
	struct drm_i915_private *dev_priv = fbc->i915;
348 349 350 351 352 353 354 355 356 357 358 359 360

	spin_lock_irq(&dev_priv->uncore.lock);
	intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
			  intel_de_read_fw(dev_priv, DSPSURF(i9xx_plane)));
	spin_unlock_irq(&dev_priv->uncore.lock);
}

static const struct intel_fbc_funcs i965_fbc_funcs = {
	.activate = i8xx_fbc_activate,
	.deactivate = i8xx_fbc_deactivate,
	.is_active = i8xx_fbc_is_active,
	.is_compressing = i8xx_fbc_is_compressing,
	.nuke = i965_fbc_nuke,
361
	.program_cfb = i8xx_fbc_program_cfb,
362 363
};

364
static u32 g4x_dpfc_ctl_limit(struct intel_fbc *fbc)
365
{
366
	switch (fbc->limit) {
367
	default:
368
		MISSING_CASE(fbc->limit);
369 370 371 372 373 374 375 376 377 378
		fallthrough;
	case 1:
		return DPFC_CTL_LIMIT_1X;
	case 2:
		return DPFC_CTL_LIMIT_2X;
	case 4:
		return DPFC_CTL_LIMIT_4X;
	}
}

379
static u32 g4x_dpfc_ctl(struct intel_fbc *fbc)
380
{
V
Ville Syrjälä 已提交
381
	const struct intel_fbc_state *fbc_state = &fbc->state;
382
	struct drm_i915_private *i915 = fbc->i915;
383 384
	u32 dpfc_ctl;

385
	dpfc_ctl = g4x_dpfc_ctl_limit(fbc) |
V
Ville Syrjälä 已提交
386
		DPFC_CTL_PLANE_G4X(fbc_state->plane->i9xx_plane);
387

388
	if (IS_G4X(i915))
389
		dpfc_ctl |= DPFC_CTL_SR_EN;
390

V
Ville Syrjälä 已提交
391
	if (fbc_state->fence_id >= 0) {
392
		dpfc_ctl |= DPFC_CTL_FENCE_EN_G4X;
393 394

		if (DISPLAY_VER(i915) < 6)
V
Ville Syrjälä 已提交
395
			dpfc_ctl |= DPFC_CTL_FENCENO(fbc_state->fence_id);
396 397 398 399 400
	}

	return dpfc_ctl;
}

401
static void g4x_fbc_activate(struct intel_fbc *fbc)
402
{
V
Ville Syrjälä 已提交
403
	const struct intel_fbc_state *fbc_state = &fbc->state;
404
	struct drm_i915_private *i915 = fbc->i915;
405

V
Ville Syrjälä 已提交
406
	intel_de_write(i915, DPFC_FENCE_YOFF,
V
Ville Syrjälä 已提交
407
		       fbc_state->fence_y_offset);
408

V
Ville Syrjälä 已提交
409
	intel_de_write(i915, DPFC_CONTROL,
410
		       DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
411 412
}

413
static void g4x_fbc_deactivate(struct intel_fbc *fbc)
414
{
415
	struct drm_i915_private *i915 = fbc->i915;
416 417 418
	u32 dpfc_ctl;

	/* Disable compression */
V
Ville Syrjälä 已提交
419
	dpfc_ctl = intel_de_read(i915, DPFC_CONTROL);
420 421
	if (dpfc_ctl & DPFC_CTL_EN) {
		dpfc_ctl &= ~DPFC_CTL_EN;
V
Ville Syrjälä 已提交
422
		intel_de_write(i915, DPFC_CONTROL, dpfc_ctl);
423 424 425
	}
}

426
static bool g4x_fbc_is_active(struct intel_fbc *fbc)
427
{
428
	return intel_de_read(fbc->i915, DPFC_CONTROL) & DPFC_CTL_EN;
429 430
}

431
static bool g4x_fbc_is_compressing(struct intel_fbc *fbc)
432
{
433
	return intel_de_read(fbc->i915, DPFC_STATUS) & DPFC_COMP_SEG_MASK;
434 435
}

436
static void g4x_fbc_program_cfb(struct intel_fbc *fbc)
437
{
438
	struct drm_i915_private *i915 = fbc->i915;
439 440 441 442

	intel_de_write(i915, DPFC_CB_BASE, fbc->compressed_fb.start);
}

443 444 445 446 447
static const struct intel_fbc_funcs g4x_fbc_funcs = {
	.activate = g4x_fbc_activate,
	.deactivate = g4x_fbc_deactivate,
	.is_active = g4x_fbc_is_active,
	.is_compressing = g4x_fbc_is_compressing,
448
	.nuke = i965_fbc_nuke,
449
	.program_cfb = g4x_fbc_program_cfb,
450 451
};

452
static void ilk_fbc_activate(struct intel_fbc *fbc)
453
{
V
Ville Syrjälä 已提交
454
	struct intel_fbc_state *fbc_state = &fbc->state;
455
	struct drm_i915_private *i915 = fbc->i915;
456

V
Ville Syrjälä 已提交
457
	intel_de_write(i915, ILK_DPFC_FENCE_YOFF,
V
Ville Syrjälä 已提交
458
		       fbc_state->fence_y_offset);
459

V
Ville Syrjälä 已提交
460
	intel_de_write(i915, ILK_DPFC_CONTROL,
461
		       DPFC_CTL_EN | g4x_dpfc_ctl(fbc));
462 463
}

464
static void ilk_fbc_deactivate(struct intel_fbc *fbc)
465
{
466
	struct drm_i915_private *i915 = fbc->i915;
467 468 469
	u32 dpfc_ctl;

	/* Disable compression */
V
Ville Syrjälä 已提交
470
	dpfc_ctl = intel_de_read(i915, ILK_DPFC_CONTROL);
471 472
	if (dpfc_ctl & DPFC_CTL_EN) {
		dpfc_ctl &= ~DPFC_CTL_EN;
V
Ville Syrjälä 已提交
473
		intel_de_write(i915, ILK_DPFC_CONTROL, dpfc_ctl);
474 475 476
	}
}

477
static bool ilk_fbc_is_active(struct intel_fbc *fbc)
478
{
479
	return intel_de_read(fbc->i915, ILK_DPFC_CONTROL) & DPFC_CTL_EN;
480 481
}

482
static bool ilk_fbc_is_compressing(struct intel_fbc *fbc)
483
{
484
	return intel_de_read(fbc->i915, ILK_DPFC_STATUS) & DPFC_COMP_SEG_MASK;
485 486
}

487
static void ilk_fbc_program_cfb(struct intel_fbc *fbc)
488
{
489
	struct drm_i915_private *i915 = fbc->i915;
490 491 492 493

	intel_de_write(i915, ILK_DPFC_CB_BASE, fbc->compressed_fb.start);
}

494 495 496 497 498
static const struct intel_fbc_funcs ilk_fbc_funcs = {
	.activate = ilk_fbc_activate,
	.deactivate = ilk_fbc_deactivate,
	.is_active = ilk_fbc_is_active,
	.is_compressing = ilk_fbc_is_compressing,
499
	.nuke = i965_fbc_nuke,
500
	.program_cfb = ilk_fbc_program_cfb,
501 502
};

503
static void snb_fbc_program_fence(struct intel_fbc *fbc)
504
{
V
Ville Syrjälä 已提交
505
	const struct intel_fbc_state *fbc_state = &fbc->state;
506
	struct drm_i915_private *i915 = fbc->i915;
507 508
	u32 ctl = 0;

V
Ville Syrjälä 已提交
509 510
	if (fbc_state->fence_id >= 0)
		ctl = SNB_DPFC_FENCE_EN | SNB_DPFC_FENCENO(fbc_state->fence_id);
511 512

	intel_de_write(i915, SNB_DPFC_CTL_SA, ctl);
V
Ville Syrjälä 已提交
513
	intel_de_write(i915, SNB_DPFC_CPU_FENCE_OFFSET, fbc_state->fence_y_offset);
514 515
}

516
static void snb_fbc_activate(struct intel_fbc *fbc)
517
{
518
	snb_fbc_program_fence(fbc);
519

520
	ilk_fbc_activate(fbc);
521 522
}

523
static void snb_fbc_nuke(struct intel_fbc *fbc)
524
{
525 526
	struct drm_i915_private *i915 = fbc->i915;

V
Ville Syrjälä 已提交
527 528
	intel_de_write(i915, MSG_FBC_REND_STATE, FBC_REND_NUKE);
	intel_de_posting_read(i915, MSG_FBC_REND_STATE);
529 530 531 532 533 534 535 536
}

static const struct intel_fbc_funcs snb_fbc_funcs = {
	.activate = snb_fbc_activate,
	.deactivate = ilk_fbc_deactivate,
	.is_active = ilk_fbc_is_active,
	.is_compressing = ilk_fbc_is_compressing,
	.nuke = snb_fbc_nuke,
537
	.program_cfb = ilk_fbc_program_cfb,
538 539
};

540
static void glk_fbc_program_cfb_stride(struct intel_fbc *fbc)
541
{
V
Ville Syrjälä 已提交
542
	const struct intel_fbc_state *fbc_state = &fbc->state;
543
	struct drm_i915_private *i915 = fbc->i915;
544
	u32 val = 0;
545

V
Ville Syrjälä 已提交
546
	if (fbc_state->override_cfb_stride)
547
		val |= FBC_STRIDE_OVERRIDE |
V
Ville Syrjälä 已提交
548
			FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
549

550 551
	intel_de_write(i915, GLK_FBC_STRIDE, val);
}
552

553
static void skl_fbc_program_cfb_stride(struct intel_fbc *fbc)
554
{
V
Ville Syrjälä 已提交
555
	const struct intel_fbc_state *fbc_state = &fbc->state;
556
	struct drm_i915_private *i915 = fbc->i915;
557
	u32 val = 0;
558

559
	/* Display WA #0529: skl, kbl, bxt. */
V
Ville Syrjälä 已提交
560
	if (fbc_state->override_cfb_stride)
561
		val |= CHICKEN_FBC_STRIDE_OVERRIDE |
V
Ville Syrjälä 已提交
562
			CHICKEN_FBC_STRIDE(fbc_state->override_cfb_stride / fbc->limit);
563

564 565 566 567 568
	intel_de_rmw(i915, CHICKEN_MISC_4,
		     CHICKEN_FBC_STRIDE_OVERRIDE |
		     CHICKEN_FBC_STRIDE_MASK, val);
}

569
static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
570
{
V
Ville Syrjälä 已提交
571
	const struct intel_fbc_state *fbc_state = &fbc->state;
572
	struct drm_i915_private *i915 = fbc->i915;
573 574
	u32 dpfc_ctl;

575
	dpfc_ctl = g4x_dpfc_ctl_limit(fbc);
576

577
	if (IS_IVYBRIDGE(i915))
V
Ville Syrjälä 已提交
578
		dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
579

V
Ville Syrjälä 已提交
580
	if (fbc_state->fence_id >= 0)
581
		dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB;
582

583
	if (fbc->false_color)
584
		dpfc_ctl |= DPFC_CTL_FALSE_COLOR;
585

586 587 588
	return dpfc_ctl;
}

589
static void ivb_fbc_activate(struct intel_fbc *fbc)
590
{
591 592
	struct drm_i915_private *i915 = fbc->i915;

V
Ville Syrjälä 已提交
593
	if (DISPLAY_VER(i915) >= 10)
594
		glk_fbc_program_cfb_stride(fbc);
V
Ville Syrjälä 已提交
595
	else if (DISPLAY_VER(i915) == 9)
596
		skl_fbc_program_cfb_stride(fbc);
597

V
Ville Syrjälä 已提交
598
	if (i915->ggtt.num_fences)
599
		snb_fbc_program_fence(fbc);
600

V
Ville Syrjälä 已提交
601
	intel_de_write(i915, ILK_DPFC_CONTROL,
602
		       DPFC_CTL_EN | ivb_dpfc_ctl(fbc));
603 604
}

605
static bool ivb_fbc_is_compressing(struct intel_fbc *fbc)
606
{
607
	return intel_de_read(fbc->i915, ILK_DPFC_STATUS2) & DPFC_COMP_SEG_MASK_IVB;
608 609
}

610
static void ivb_fbc_set_false_color(struct intel_fbc *fbc,
611 612
				    bool enable)
{
613
	intel_de_rmw(fbc->i915, ILK_DPFC_CONTROL,
614
		     DPFC_CTL_FALSE_COLOR, enable ? DPFC_CTL_FALSE_COLOR : 0);
615 616
}

V
Ville Syrjälä 已提交
617 618
static const struct intel_fbc_funcs ivb_fbc_funcs = {
	.activate = ivb_fbc_activate,
619 620
	.deactivate = ilk_fbc_deactivate,
	.is_active = ilk_fbc_is_active,
V
Ville Syrjälä 已提交
621
	.is_compressing = ivb_fbc_is_compressing,
622
	.nuke = snb_fbc_nuke,
623
	.program_cfb = ilk_fbc_program_cfb,
624
	.set_false_color = ivb_fbc_set_false_color,
625 626
};

627
static bool intel_fbc_hw_is_active(struct intel_fbc *fbc)
628
{
629
	return fbc->funcs->is_active(fbc);
630 631
}

632
static void intel_fbc_hw_activate(struct intel_fbc *fbc)
633
{
V
Ville Syrjälä 已提交
634
	trace_intel_fbc_activate(fbc->state.plane);
635

636
	fbc->active = true;
637
	fbc->activated = true;
638

639
	fbc->funcs->activate(fbc);
640 641
}

642
static void intel_fbc_hw_deactivate(struct intel_fbc *fbc)
643
{
V
Ville Syrjälä 已提交
644
	trace_intel_fbc_deactivate(fbc->state.plane);
645

646 647
	fbc->active = false;

648
	fbc->funcs->deactivate(fbc);
649 650
}

651
static bool intel_fbc_is_compressing(struct intel_fbc *fbc)
652
{
653
	return fbc->funcs->is_compressing(fbc);
654 655
}

656
static void intel_fbc_nuke(struct intel_fbc *fbc)
657
{
V
Ville Syrjälä 已提交
658
	trace_intel_fbc_nuke(fbc->state.plane);
659

660
	fbc->funcs->nuke(fbc);
661 662
}

663
static void intel_fbc_activate(struct intel_fbc *fbc)
664
{
665 666
	intel_fbc_hw_activate(fbc);
	intel_fbc_nuke(fbc);
V
Ville Syrjälä 已提交
667 668

	fbc->no_fbc_reason = NULL;
669 670
}

671
static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
P
Paulo Zanoni 已提交
672
{
673
	struct drm_i915_private *i915 = fbc->i915;
674

V
Ville Syrjälä 已提交
675
	drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
P
Paulo Zanoni 已提交
676

677
	if (fbc->active)
678
		intel_fbc_hw_deactivate(fbc);
679 680

	fbc->no_fbc_reason = reason;
681 682
}

683 684
static u64 intel_fbc_cfb_base_max(struct drm_i915_private *i915)
{
685
	if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915))
686 687 688 689 690
		return BIT_ULL(28);
	else
		return BIT_ULL(32);
}

V
Ville Syrjälä 已提交
691
static u64 intel_fbc_stolen_end(struct drm_i915_private *i915)
692
{
693 694 695 696 697 698
	u64 end;

	/* The FBC hardware for BDW/SKL doesn't have access to the stolen
	 * reserved range size, so it always assumes the maximum (8mb) is used.
	 * If we enable FBC using a CFB on that memory range we'll get FIFO
	 * underruns, even if that range is not reserved by the BIOS. */
V
Ville Syrjälä 已提交
699 700 701
	if (IS_BROADWELL(i915) ||
	    (DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915)))
		end = resource_size(&i915->dsm) - 8 * 1024 * 1024;
702
	else
703
		end = U64_MAX;
704

V
Ville Syrjälä 已提交
705
	return min(end, intel_fbc_cfb_base_max(i915));
706 707
}

708
static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)
709
{
V
Ville Syrjälä 已提交
710
	return plane_state->hw.fb->format->cpp[0] == 2 ? 2 : 1;
711 712
}

V
Ville Syrjälä 已提交
713
static int intel_fbc_max_limit(struct drm_i915_private *i915)
714 715
{
	/* WaFbcOnly1to1Ratio:ctg */
V
Ville Syrjälä 已提交
716
	if (IS_G4X(i915))
717 718
		return 1;

719 720 721 722
	/*
	 * FBC2 can only do 1:1, 1:2, 1:4, we limit
	 * FBC1 to the same out of convenience.
	 */
723
	return 4;
724 725
}

726
static int find_compression_limit(struct intel_fbc *fbc,
727
				  unsigned int size, int min_limit)
728
{
729
	struct drm_i915_private *i915 = fbc->i915;
V
Ville Syrjälä 已提交
730
	u64 end = intel_fbc_stolen_end(i915);
731 732 733
	int ret, limit = min_limit;

	size /= limit;
734 735

	/* Try to over-allocate to reduce reallocations and fragmentation. */
V
Ville Syrjälä 已提交
736
	ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
737
						   size <<= 1, 4096, 0, end);
738
	if (ret == 0)
739
		return limit;
740

V
Ville Syrjälä 已提交
741 742
	for (; limit <= intel_fbc_max_limit(i915); limit <<= 1) {
		ret = i915_gem_stolen_insert_node_in_range(i915, &fbc->compressed_fb,
743 744 745
							   size >>= 1, 4096, 0, end);
		if (ret == 0)
			return limit;
746
	}
747 748

	return 0;
749 750
}

751
static int intel_fbc_alloc_cfb(struct intel_fbc *fbc,
752
			       unsigned int size, int min_limit)
753
{
754
	struct drm_i915_private *i915 = fbc->i915;
755
	int ret;
756

V
Ville Syrjälä 已提交
757
	drm_WARN_ON(&i915->drm,
758
		    drm_mm_node_allocated(&fbc->compressed_fb));
V
Ville Syrjälä 已提交
759
	drm_WARN_ON(&i915->drm,
760
		    drm_mm_node_allocated(&fbc->compressed_llb));
761

V
Ville Syrjälä 已提交
762 763
	if (DISPLAY_VER(i915) < 5 && !IS_G4X(i915)) {
		ret = i915_gem_stolen_insert_node(i915, &fbc->compressed_llb,
764 765 766 767 768
						  4096, 4096);
		if (ret)
			goto err;
	}

769
	ret = find_compression_limit(fbc, size, min_limit);
770 771
	if (!ret)
		goto err_llb;
772
	else if (ret > min_limit)
V
Ville Syrjälä 已提交
773
		drm_info_once(&i915->drm,
774
			      "Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
775

776
	fbc->limit = ret;
777

V
Ville Syrjälä 已提交
778
	drm_dbg_kms(&i915->drm,
779 780
		    "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
		    fbc->compressed_fb.size, fbc->limit);
781 782 783 784

	return 0;

err_llb:
785
	if (drm_mm_node_allocated(&fbc->compressed_llb))
V
Ville Syrjälä 已提交
786
		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
787
err:
V
Ville Syrjälä 已提交
788 789
	if (drm_mm_initialized(&i915->mm.stolen))
		drm_info_once(&i915->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
790 791 792
	return -ENOSPC;
}

793
static void intel_fbc_program_cfb(struct intel_fbc *fbc)
794
{
795
	fbc->funcs->program_cfb(fbc);
796 797
}

798
static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
799
{
800
	struct drm_i915_private *i915 = fbc->i915;
801

802
	if (WARN_ON(intel_fbc_hw_is_active(fbc)))
803 804
		return;

805
	if (drm_mm_node_allocated(&fbc->compressed_llb))
V
Ville Syrjälä 已提交
806
		i915_gem_stolen_remove_node(i915, &fbc->compressed_llb);
807
	if (drm_mm_node_allocated(&fbc->compressed_fb))
V
Ville Syrjälä 已提交
808
		i915_gem_stolen_remove_node(i915, &fbc->compressed_fb);
809 810
}

811
void intel_fbc_cleanup(struct drm_i915_private *i915)
P
Paulo Zanoni 已提交
812
{
813
	struct intel_fbc *fbc = i915->fbc;
814

815
	if (!fbc)
816 817
		return;

818
	mutex_lock(&fbc->lock);
819
	__intel_fbc_cleanup_cfb(fbc);
820
	mutex_unlock(&fbc->lock);
821 822

	kfree(fbc);
P
Paulo Zanoni 已提交
823 824
}

825
static bool stride_is_valid(const struct intel_plane_state *plane_state)
826
{
827 828 829 830 831
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	unsigned int stride = intel_fbc_plane_stride(plane_state) *
		fb->format->cpp[0];

832
	/* This should have been caught earlier. */
V
Ville Syrjälä 已提交
833
	if (drm_WARN_ON_ONCE(&i915->drm, (stride & (64 - 1)) != 0))
834
		return false;
835 836

	/* Below are the additional FBC restrictions. */
837 838
	if (stride < 512)
		return false;
839

V
Ville Syrjälä 已提交
840
	if (DISPLAY_VER(i915) == 2 || DISPLAY_VER(i915) == 3)
841 842
		return stride == 4096 || stride == 8192;

V
Ville Syrjälä 已提交
843
	if (DISPLAY_VER(i915) == 4 && !IS_G4X(i915) && stride < 2048)
844 845
		return false;

846
	/* Display WA #1105: skl,bxt,kbl,cfl,glk */
V
Ville Syrjälä 已提交
847
	if ((DISPLAY_VER(i915) == 9 || IS_GEMINILAKE(i915)) &&
848
	    fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
849 850
		return false;

851 852 853 854 855 856
	if (stride > 16384)
		return false;

	return true;
}

857
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
858
{
859 860 861 862
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	const struct drm_framebuffer *fb = plane_state->hw.fb;

	switch (fb->format->format) {
863 864 865 866 867 868
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_XBGR8888:
		return true;
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_RGB565:
		/* 16bpp not supported on gen2 */
V
Ville Syrjälä 已提交
869
		if (DISPLAY_VER(i915) == 2)
870 871
			return false;
		/* WaFbcOnly1to1Ratio:ctg */
V
Ville Syrjälä 已提交
872
		if (IS_G4X(i915))
873 874 875 876 877 878 879
			return false;
		return true;
	default:
		return false;
	}
}

880
static bool rotation_is_valid(const struct intel_plane_state *plane_state)
881
{
882 883 884 885 886
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	unsigned int rotation = plane_state->hw.rotation;

	if (DISPLAY_VER(i915) >= 9 && fb->format->format == DRM_FORMAT_RGB565 &&
887 888
	    drm_rotation_90_or_270(rotation))
		return false;
V
Ville Syrjälä 已提交
889
	else if (DISPLAY_VER(i915) <= 4 && !IS_G4X(i915) &&
890 891 892 893 894 895
		 rotation != DRM_MODE_ROTATE_0)
		return false;

	return true;
}

896 897 898
/*
 * For some reason, the hardware tracking starts looking at whatever we
 * programmed as the display plane base address register. It does not look at
899 900
 * the X and Y offset registers. That's why we include the src x/y offsets
 * instead of just looking at the plane size.
901
 */
902
static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *plane_state)
903
{
904
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
905
	unsigned int effective_w, effective_h, max_w, max_h;
906

V
Ville Syrjälä 已提交
907
	if (DISPLAY_VER(i915) >= 10) {
908 909
		max_w = 5120;
		max_h = 4096;
V
Ville Syrjälä 已提交
910
	} else if (DISPLAY_VER(i915) >= 8 || IS_HASWELL(i915)) {
911 912
		max_w = 4096;
		max_h = 4096;
V
Ville Syrjälä 已提交
913
	} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) {
914 915 916 917 918 919 920
		max_w = 4096;
		max_h = 2048;
	} else {
		max_w = 2048;
		max_h = 1536;
	}

921 922 923 924
	effective_w = plane_state->view.color_plane[0].x +
		(drm_rect_width(&plane_state->uapi.src) >> 16);
	effective_h = plane_state->view.color_plane[0].y +
		(drm_rect_height(&plane_state->uapi.src) >> 16);
925 926

	return effective_w <= max_w && effective_h <= max_h;
927 928
}

929
static bool tiling_is_valid(const struct intel_plane_state *plane_state)
930
{
931 932 933 934
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
	const struct drm_framebuffer *fb = plane_state->hw.fb;

	switch (fb->modifier) {
935 936
	case DRM_FORMAT_MOD_LINEAR:
	case I915_FORMAT_MOD_Y_TILED:
937
	case I915_FORMAT_MOD_Yf_TILED:
V
Ville Syrjälä 已提交
938
		return DISPLAY_VER(i915) >= 9;
939
	case I915_FORMAT_MOD_X_TILED:
940 941 942 943 944 945
		return true;
	default:
		return false;
	}
}

V
Ville Syrjälä 已提交
946 947 948
static void intel_fbc_update_state(struct intel_atomic_state *state,
				   struct intel_crtc *crtc,
				   struct intel_plane *plane)
949
{
950 951 952 953 954 955
	struct drm_i915_private *i915 = to_i915(state->base.dev);
	const struct intel_crtc_state *crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);
	const struct intel_plane_state *plane_state =
		intel_atomic_get_new_plane_state(state, plane);
	struct intel_fbc *fbc = plane->fbc;
V
Ville Syrjälä 已提交
956
	struct intel_fbc_state *fbc_state = &fbc->state;
957

V
Ville Syrjälä 已提交
958
	WARN_ON(plane_state->no_fbc_reason);
959

V
Ville Syrjälä 已提交
960
	fbc_state->plane = plane;
961

962
	/* FBC1 compression interval: arbitrary choice of 1 second */
V
Ville Syrjälä 已提交
963
	fbc_state->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode);
964

V
Ville Syrjälä 已提交
965
	fbc_state->fence_y_offset = intel_plane_fence_y_offset(plane_state);
966

V
Ville Syrjälä 已提交
967
	drm_WARN_ON(&i915->drm, plane_state->flags & PLANE_HAS_FENCE &&
968
		    !plane_state->ggtt_vma->fence);
969 970

	if (plane_state->flags & PLANE_HAS_FENCE &&
971
	    plane_state->ggtt_vma->fence)
V
Ville Syrjälä 已提交
972
		fbc_state->fence_id = plane_state->ggtt_vma->fence->id;
973
	else
V
Ville Syrjälä 已提交
974
		fbc_state->fence_id = -1;
975

V
Ville Syrjälä 已提交
976 977 978
	fbc_state->cfb_stride = intel_fbc_cfb_stride(plane_state);
	fbc_state->cfb_size = intel_fbc_cfb_size(plane_state);
	fbc_state->override_cfb_stride = intel_fbc_override_cfb_stride(plane_state);
979 980
}

V
Ville Syrjälä 已提交
981
static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
982
{
V
Ville Syrjälä 已提交
983
	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
984

V
Ville Syrjälä 已提交
985 986
	/* The use of a CPU fence is one of two ways to detect writes by the
	 * CPU to the scanout and trigger updates to the FBC.
987
	 *
V
Ville Syrjälä 已提交
988 989 990 991 992 993 994 995 996 997 998 999 1000
	 * The other method is by software tracking (see
	 * intel_fbc_invalidate/flush()), it will manually notify FBC and nuke
	 * the current compressed buffer and recompress it.
	 *
	 * Note that is possible for a tiled surface to be unmappable (and
	 * so have no fence associated with it) due to aperture constraints
	 * at the time of pinning.
	 *
	 * FIXME with 90/270 degree rotation we should use the fence on
	 * the normal GTT view (the rotated view doesn't even have a
	 * fence). Would need changes to the FBC fence Y offset as well.
	 * For now this will effectively disable FBC with 90/270 degree
	 * rotation.
1001
	 */
V
Ville Syrjälä 已提交
1002 1003 1004
	return DISPLAY_VER(i915) >= 9 ||
		(plane_state->flags & PLANE_HAS_FENCE &&
		 plane_state->ggtt_vma->fence);
1005 1006
}

V
Ville Syrjälä 已提交
1007
static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state)
1008
{
V
Ville Syrjälä 已提交
1009 1010
	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
	struct intel_fbc *fbc = plane->fbc;
1011

V
Ville Syrjälä 已提交
1012 1013 1014
	return intel_fbc_min_limit(plane_state) <= fbc->limit &&
		intel_fbc_cfb_size(plane_state) <= fbc->compressed_fb.size * fbc->limit;
}
1015

V
Ville Syrjälä 已提交
1016
static bool intel_fbc_is_ok(const struct intel_plane_state *plane_state)
1017
{
V
Ville Syrjälä 已提交
1018 1019 1020
	return !plane_state->no_fbc_reason &&
		intel_fbc_is_fence_ok(plane_state) &&
		intel_fbc_is_cfb_ok(plane_state);
1021 1022
}

1023 1024
static int intel_fbc_check_plane(struct intel_atomic_state *state,
				 struct intel_plane *plane)
1025
{
1026 1027 1028 1029 1030 1031 1032
	struct drm_i915_private *i915 = to_i915(state->base.dev);
	struct intel_plane_state *plane_state =
		intel_atomic_get_new_plane_state(state, plane);
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc);
	const struct intel_crtc_state *crtc_state;
	struct intel_fbc *fbc = plane->fbc;
1033

1034 1035
	if (!fbc)
		return 0;
1036

1037 1038 1039
	if (intel_vgpu_active(i915)) {
		plane_state->no_fbc_reason = "VGPU active";
		return 0;
1040 1041
	}

1042 1043 1044
	if (!i915->params.enable_fbc) {
		plane_state->no_fbc_reason = "disabled per module param or by default";
		return 0;
1045 1046
	}

1047 1048 1049
	if (!plane_state->uapi.visible) {
		plane_state->no_fbc_reason = "plane not visible";
		return 0;
1050 1051
	}

1052 1053 1054 1055 1056
	crtc_state = intel_atomic_get_new_crtc_state(state, crtc);

	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
		plane_state->no_fbc_reason = "interlaced mode not supported";
		return 0;
1057
	}
1058

1059 1060 1061
	if (crtc_state->double_wide) {
		plane_state->no_fbc_reason = "double wide pipe not supported";
		return 0;
1062
	}
1063

1064 1065 1066 1067 1068 1069 1070
	/*
	 * Display 12+ is not supporting FBC with PSR2.
	 * Recommendation is to keep this combination disabled
	 * Bspec: 50422 HSD: 14010260002
	 */
	if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) {
		plane_state->no_fbc_reason = "PSR2 enabled";
1071 1072 1073
		return false;
	}

1074 1075 1076
	if (!pixel_format_is_valid(plane_state)) {
		plane_state->no_fbc_reason = "pixel format not supported";
		return 0;
1077 1078
	}

1079 1080 1081
	if (!tiling_is_valid(plane_state)) {
		plane_state->no_fbc_reason = "tiling not supported";
		return 0;
1082 1083
	}

1084 1085 1086
	if (!rotation_is_valid(plane_state)) {
		plane_state->no_fbc_reason = "rotation not supported";
		return 0;
1087 1088
	}

1089 1090 1091
	if (!stride_is_valid(plane_state)) {
		plane_state->no_fbc_reason = "stride not supported";
		return 0;
1092 1093
	}

1094 1095 1096
	if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
	    fb->format->has_alpha) {
		plane_state->no_fbc_reason = "per-pixel alpha not supported";
1097
		return false;
1098 1099
	}

1100 1101 1102
	if (!intel_fbc_hw_tracking_covers_screen(plane_state)) {
		plane_state->no_fbc_reason = "plane size too big";
		return 0;
1103 1104
	}

1105 1106 1107 1108 1109
	/*
	 * Work around a problem on GEN9+ HW, where enabling FBC on a plane
	 * having a Y offset that isn't divisible by 4 causes FIFO underrun
	 * and screen flicker.
	 */
V
Ville Syrjälä 已提交
1110
	if (DISPLAY_VER(i915) >= 9 &&
1111 1112
	    plane_state->view.color_plane[0].y & 3) {
		plane_state->no_fbc_reason = "plane start Y offset misaligned";
1113 1114 1115
		return false;
	}

1116
	/* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
V
Ville Syrjälä 已提交
1117
	if (DISPLAY_VER(i915) >= 11 &&
1118 1119
	    (plane_state->view.color_plane[0].y + drm_rect_height(&plane_state->uapi.src)) & 3) {
		plane_state->no_fbc_reason = "plane end Y offset misaligned";
1120 1121 1122
		return false;
	}

1123 1124 1125
	/* WaFbcExceedCdClockThreshold:hsw,bdw */
	if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
		const struct intel_cdclk_state *cdclk_state;
1126

1127 1128 1129
		cdclk_state = intel_atomic_get_cdclk_state(state);
		if (IS_ERR(cdclk_state))
			return PTR_ERR(cdclk_state);
1130

1131 1132 1133 1134 1135
		if (crtc_state->pixel_rate >= cdclk_state->logical.cdclk * 95 / 100) {
			plane_state->no_fbc_reason = "pixel rate too high";
			return 0;
		}
	}
1136

1137
	plane_state->no_fbc_reason = NULL;
1138

1139
	return 0;
1140 1141
}

1142

1143 1144 1145
static bool intel_fbc_can_flip_nuke(struct intel_atomic_state *state,
				    struct intel_crtc *crtc,
				    struct intel_plane *plane)
1146
{
1147 1148 1149 1150 1151 1152 1153 1154
	const struct intel_crtc_state *new_crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);
	const struct intel_plane_state *old_plane_state =
		intel_atomic_get_old_plane_state(state, plane);
	const struct intel_plane_state *new_plane_state =
		intel_atomic_get_new_plane_state(state, plane);
	const struct drm_framebuffer *old_fb = old_plane_state->hw.fb;
	const struct drm_framebuffer *new_fb = new_plane_state->hw.fb;
1155

1156
	if (drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
1157 1158
		return false;

V
Ville Syrjälä 已提交
1159 1160
	if (!intel_fbc_is_ok(old_plane_state) ||
	    !intel_fbc_is_ok(new_plane_state))
1161 1162
		return false;

1163
	if (old_fb->format->format != new_fb->format->format)
1164 1165
		return false;

1166
	if (old_fb->modifier != new_fb->modifier)
1167 1168
		return false;

1169 1170
	if (intel_fbc_plane_stride(old_plane_state) !=
	    intel_fbc_plane_stride(new_plane_state))
1171 1172
		return false;

V
Ville Syrjälä 已提交
1173 1174
	if (intel_fbc_cfb_stride(old_plane_state) !=
	    intel_fbc_cfb_stride(new_plane_state))
1175 1176
		return false;

V
Ville Syrjälä 已提交
1177 1178
	if (intel_fbc_cfb_size(old_plane_state) !=
	    intel_fbc_cfb_size(new_plane_state))
1179 1180
		return false;

V
Ville Syrjälä 已提交
1181 1182
	if (intel_fbc_override_cfb_stride(old_plane_state) !=
	    intel_fbc_override_cfb_stride(new_plane_state))
1183 1184 1185 1186 1187
		return false;

	return true;
}

1188 1189 1190
static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
				   struct intel_crtc *crtc,
				   struct intel_plane *plane)
1191
{
1192
	struct drm_i915_private *i915 = to_i915(state->base.dev);
1193
	struct intel_fbc *fbc = plane->fbc;
1194
	bool need_vblank_wait = false;
1195

1196
	fbc->flip_pending = true;
1197

1198
	if (intel_fbc_can_flip_nuke(state, crtc, plane))
1199 1200
		return need_vblank_wait;

1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
	intel_fbc_deactivate(fbc, "update pending");

	/*
	 * Display WA #1198: glk+
	 * Need an extra vblank wait between FBC disable and most plane
	 * updates. Bspec says this is only needed for plane disable, but
	 * that is not true. Touching most plane registers will cause the
	 * corruption to appear. Also SKL/derivatives do not seem to be
	 * affected.
	 *
	 * TODO: could optimize this a bit by sampling the frame
	 * counter when we disable FBC (if it was already done earlier)
	 * and skipping the extra vblank wait before the plane update
	 * if at least one frame has already passed.
	 */
	if (fbc->activated && DISPLAY_VER(i915) >= 10)
		need_vblank_wait = true;
	fbc->activated = false;
1219

1220 1221
	return need_vblank_wait;
}
1222

1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
bool intel_fbc_pre_update(struct intel_atomic_state *state,
			  struct intel_crtc *crtc)
{
	const struct intel_plane_state *plane_state;
	bool need_vblank_wait = false;
	struct intel_plane *plane;
	int i;

	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
		struct intel_fbc *fbc = plane->fbc;
1233

1234 1235 1236 1237 1238
		if (!fbc || plane->pipe != crtc->pipe)
			continue;

		mutex_lock(&fbc->lock);

V
Ville Syrjälä 已提交
1239
		if (fbc->state.plane == plane)
1240 1241 1242
			need_vblank_wait |= __intel_fbc_pre_update(state, crtc, plane);

		mutex_unlock(&fbc->lock);
1243 1244 1245
	}

	return need_vblank_wait;
1246 1247
}

1248
static void __intel_fbc_disable(struct intel_fbc *fbc)
1249
{
1250
	struct drm_i915_private *i915 = fbc->i915;
V
Ville Syrjälä 已提交
1251
	struct intel_plane *plane = fbc->state.plane;
1252

V
Ville Syrjälä 已提交
1253 1254
	drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
	drm_WARN_ON(&i915->drm, fbc->active);
1255

1256 1257
	drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n",
		    plane->base.base.id, plane->base.name);
1258

1259
	__intel_fbc_cleanup_cfb(fbc);
1260

V
Ville Syrjälä 已提交
1261
	fbc->state.plane = NULL;
1262 1263
}

1264
static void __intel_fbc_post_update(struct intel_fbc *fbc)
1265
{
1266
	struct drm_i915_private *i915 = fbc->i915;
1267

V
Ville Syrjälä 已提交
1268
	drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
1269

1270
	if (!fbc->busy_bits)
1271
		intel_fbc_activate(fbc);
1272
	else
1273
		intel_fbc_deactivate(fbc, "frontbuffer write");
P
Paulo Zanoni 已提交
1274 1275
}

1276 1277
void intel_fbc_post_update(struct intel_atomic_state *state,
			   struct intel_crtc *crtc)
P
Paulo Zanoni 已提交
1278
{
1279 1280 1281
	const struct intel_plane_state *plane_state;
	struct intel_plane *plane;
	int i;
1282

1283 1284
	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
		struct intel_fbc *fbc = plane->fbc;
1285

1286 1287 1288 1289 1290
		if (!fbc || plane->pipe != crtc->pipe)
			continue;

		mutex_lock(&fbc->lock);

V
Ville Syrjälä 已提交
1291
		if (fbc->state.plane == plane) {
1292 1293 1294 1295 1296
			fbc->flip_pending = false;
			__intel_fbc_post_update(fbc);
		}

		mutex_unlock(&fbc->lock);
1297
	}
1298 1299
}

1300 1301
static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc)
{
V
Ville Syrjälä 已提交
1302 1303
	if (fbc->state.plane)
		return fbc->state.plane->frontbuffer_bit;
1304 1305 1306 1307
	else
		return fbc->possible_framebuffer_bits;
}

V
Ville Syrjälä 已提交
1308
void intel_fbc_invalidate(struct drm_i915_private *i915,
1309 1310 1311
			  unsigned int frontbuffer_bits,
			  enum fb_op_origin origin)
{
1312
	struct intel_fbc *fbc = i915->fbc;
1313

1314
	if (!fbc)
1315 1316
		return;

1317
	if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
1318 1319
		return;

1320
	mutex_lock(&fbc->lock);
P
Paulo Zanoni 已提交
1321

1322
	fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits;
1323

V
Ville Syrjälä 已提交
1324
	if (fbc->state.plane && fbc->busy_bits)
1325
		intel_fbc_deactivate(fbc, "frontbuffer write");
P
Paulo Zanoni 已提交
1326

1327
	mutex_unlock(&fbc->lock);
1328 1329
}

V
Ville Syrjälä 已提交
1330
void intel_fbc_flush(struct drm_i915_private *i915,
1331
		     unsigned int frontbuffer_bits, enum fb_op_origin origin)
1332
{
1333
	struct intel_fbc *fbc = i915->fbc;
1334

1335
	if (!fbc)
1336 1337
		return;

1338
	mutex_lock(&fbc->lock);
1339

1340
	fbc->busy_bits &= ~frontbuffer_bits;
1341

1342
	if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
1343 1344
		goto out;

V
Ville Syrjälä 已提交
1345
	if (!fbc->busy_bits && fbc->state.plane &&
1346
	    (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) {
1347
		if (fbc->active)
1348
			intel_fbc_nuke(fbc);
1349
		else if (!fbc->flip_pending)
1350
			__intel_fbc_post_update(fbc);
1351
	}
P
Paulo Zanoni 已提交
1352

1353
out:
1354
	mutex_unlock(&fbc->lock);
1355 1356
}

1357
int intel_fbc_atomic_check(struct intel_atomic_state *state)
1358
{
1359
	struct intel_plane_state *plane_state;
1360
	struct intel_plane *plane;
1361
	int i;
1362

1363
	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
1364
		int ret;
1365

1366 1367 1368
		ret = intel_fbc_check_plane(state, plane);
		if (ret)
			return ret;
1369 1370
	}

1371
	return 0;
1372 1373
}

1374 1375 1376
static void __intel_fbc_enable(struct intel_atomic_state *state,
			       struct intel_crtc *crtc,
			       struct intel_plane *plane)
1377
{
1378
	struct drm_i915_private *i915 = to_i915(state->base.dev);
1379 1380
	const struct intel_plane_state *plane_state =
		intel_atomic_get_new_plane_state(state, plane);
1381
	struct intel_fbc *fbc = plane->fbc;
1382

V
Ville Syrjälä 已提交
1383 1384
	if (fbc->state.plane) {
		if (fbc->state.plane != plane)
1385
			return;
1386

1387 1388
		if (intel_fbc_is_ok(plane_state)) {
			intel_fbc_update_state(state, crtc, plane);
1389
			return;
1390
		}
1391

1392
		__intel_fbc_disable(fbc);
1393
	}
1394

V
Ville Syrjälä 已提交
1395
	drm_WARN_ON(&i915->drm, fbc->active);
1396

V
Ville Syrjälä 已提交
1397 1398 1399
	fbc->no_fbc_reason = plane_state->no_fbc_reason;
	if (fbc->no_fbc_reason)
		return;
1400

V
Ville Syrjälä 已提交
1401 1402
	if (!intel_fbc_is_fence_ok(plane_state)) {
		fbc->no_fbc_reason = "framebuffer not fenced";
1403
		return;
V
Ville Syrjälä 已提交
1404
	}
1405

1406 1407 1408 1409
	if (fbc->underrun_detected) {
		fbc->no_fbc_reason = "FIFO underrun";
		return;
	}
1410

V
Ville Syrjälä 已提交
1411 1412
	if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(plane_state),
				intel_fbc_min_limit(plane_state))) {
1413
		fbc->no_fbc_reason = "not enough stolen memory";
1414
		return;
1415 1416
	}

1417 1418
	drm_dbg_kms(&i915->drm, "Enabling FBC on [PLANE:%d:%s]\n",
		    plane->base.base.id, plane->base.name);
1419
	fbc->no_fbc_reason = "FBC enabled but not active yet\n";
1420

V
Ville Syrjälä 已提交
1421
	intel_fbc_update_state(state, crtc, plane);
1422

1423
	intel_fbc_program_cfb(fbc);
1424 1425 1426
}

/**
1427
 * intel_fbc_disable - disable FBC if it's associated with crtc
1428 1429 1430 1431
 * @crtc: the CRTC
 *
 * This function disables FBC if it's associated with the provided CRTC.
 */
1432
void intel_fbc_disable(struct intel_crtc *crtc)
1433
{
1434 1435
	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
	struct intel_plane *plane;
1436

1437 1438
	for_each_intel_plane(&i915->drm, plane) {
		struct intel_fbc *fbc = plane->fbc;
1439

1440 1441 1442 1443
		if (!fbc || plane->pipe != crtc->pipe)
			continue;

		mutex_lock(&fbc->lock);
V
Ville Syrjälä 已提交
1444
		if (fbc->state.plane == plane)
1445 1446 1447
			__intel_fbc_disable(fbc);
		mutex_unlock(&fbc->lock);
	}
1448 1449
}

1450 1451 1452 1453 1454
void intel_fbc_update(struct intel_atomic_state *state,
		      struct intel_crtc *crtc)
{
	const struct intel_crtc_state *crtc_state =
		intel_atomic_get_new_crtc_state(state, crtc);
1455 1456 1457
	const struct intel_plane_state *plane_state;
	struct intel_plane *plane;
	int i;
1458

1459 1460
	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
		struct intel_fbc *fbc = plane->fbc;
1461

1462 1463 1464 1465 1466 1467
		if (!fbc || plane->pipe != crtc->pipe)
			continue;

		mutex_lock(&fbc->lock);

		if (crtc_state->update_pipe && plane_state->no_fbc_reason) {
V
Ville Syrjälä 已提交
1468
			if (fbc->state.plane == plane)
1469 1470 1471 1472 1473 1474 1475
				__intel_fbc_disable(fbc);
		} else {
			__intel_fbc_enable(state, crtc, plane);
		}

		mutex_unlock(&fbc->lock);
	}
1476 1477
}

1478
/**
1479
 * intel_fbc_global_disable - globally disable FBC
V
Ville Syrjälä 已提交
1480
 * @i915: i915 device instance
1481 1482 1483
 *
 * This function disables FBC regardless of which CRTC is associated with it.
 */
V
Ville Syrjälä 已提交
1484
void intel_fbc_global_disable(struct drm_i915_private *i915)
1485
{
1486
	struct intel_fbc *fbc = i915->fbc;
1487

1488
	if (!fbc)
1489 1490
		return;

1491
	mutex_lock(&fbc->lock);
V
Ville Syrjälä 已提交
1492
	if (fbc->state.plane)
1493
		__intel_fbc_disable(fbc);
1494
	mutex_unlock(&fbc->lock);
1495 1496
}

1497 1498
static void intel_fbc_underrun_work_fn(struct work_struct *work)
{
1499 1500
	struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work);
	struct drm_i915_private *i915 = fbc->i915;
1501 1502 1503 1504

	mutex_lock(&fbc->lock);

	/* Maybe we were scheduled twice. */
V
Ville Syrjälä 已提交
1505
	if (fbc->underrun_detected || !fbc->state.plane)
1506 1507
		goto out;

V
Ville Syrjälä 已提交
1508
	drm_dbg_kms(&i915->drm, "Disabling FBC due to FIFO underrun.\n");
1509 1510
	fbc->underrun_detected = true;

1511
	intel_fbc_deactivate(fbc, "FIFO underrun");
1512
	if (!fbc->flip_pending)
V
Ville Syrjälä 已提交
1513
		intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(i915, fbc->state.plane->pipe));
1514
	__intel_fbc_disable(fbc);
1515 1516 1517 1518
out:
	mutex_unlock(&fbc->lock);
}

1519 1520
/*
 * intel_fbc_reset_underrun - reset FBC fifo underrun status.
1521
 * @i915: the i915 device
1522 1523 1524 1525
 *
 * See intel_fbc_handle_fifo_underrun_irq(). For automated testing we
 * want to re-enable FBC after an underrun to increase test coverage.
 */
1526
void intel_fbc_reset_underrun(struct drm_i915_private *i915)
1527
{
1528
	struct intel_fbc *fbc = i915->fbc;
1529

1530
	if (!fbc)
1531
		return;
1532

1533
	cancel_work_sync(&fbc->underrun_work);
1534

1535
	mutex_lock(&fbc->lock);
1536

1537
	if (fbc->underrun_detected) {
V
Ville Syrjälä 已提交
1538
		drm_dbg_kms(&i915->drm,
1539
			    "Re-allowing FBC after fifo underrun\n");
1540
		fbc->no_fbc_reason = "FIFO underrun cleared";
1541 1542
	}

1543 1544
	fbc->underrun_detected = false;
	mutex_unlock(&fbc->lock);
1545 1546
}

1547 1548
/**
 * intel_fbc_handle_fifo_underrun_irq - disable FBC when we get a FIFO underrun
1549
 * @i915: i915 device
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
 *
 * Without FBC, most underruns are harmless and don't really cause too many
 * problems, except for an annoying message on dmesg. With FBC, underruns can
 * become black screens or even worse, especially when paired with bad
 * watermarks. So in order for us to be on the safe side, completely disable FBC
 * in case we ever detect a FIFO underrun on any pipe. An underrun on any pipe
 * already suggests that watermarks may be bad, so try to be as safe as
 * possible.
 *
 * This function is called from the IRQ handler.
 */
1561
void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
1562
{
1563
	struct intel_fbc *fbc = i915->fbc;
1564

1565
	if (!fbc)
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
		return;

	/* There's no guarantee that underrun_detected won't be set to true
	 * right after this check and before the work is scheduled, but that's
	 * not a problem since we'll check it again under the work function
	 * while FBC is locked. This check here is just to prevent us from
	 * unnecessarily scheduling the work, and it relies on the fact that we
	 * never switch underrun_detect back to false after it's true. */
	if (READ_ONCE(fbc->underrun_detected))
		return;

	schedule_work(&fbc->underrun_work);
}

1580 1581 1582 1583 1584 1585 1586 1587 1588
/*
 * The DDX driver changes its behavior depending on the value it reads from
 * i915.enable_fbc, so sanitize it by translating the default value into either
 * 0 or 1 in order to allow it to know what's going on.
 *
 * Notice that this is done at driver initialization and we still allow user
 * space to change the value during runtime without sanitizing it again. IGT
 * relies on being able to change i915.enable_fbc at runtime.
 */
V
Ville Syrjälä 已提交
1589
static int intel_sanitize_fbc_option(struct drm_i915_private *i915)
1590
{
V
Ville Syrjälä 已提交
1591 1592
	if (i915->params.enable_fbc >= 0)
		return !!i915->params.enable_fbc;
1593

V
Ville Syrjälä 已提交
1594
	if (!HAS_FBC(i915))
1595 1596
		return 0;

V
Ville Syrjälä 已提交
1597
	if (IS_BROADWELL(i915) || DISPLAY_VER(i915) >= 9)
1598 1599 1600 1601 1602
		return 1;

	return 0;
}

V
Ville Syrjälä 已提交
1603
static bool need_fbc_vtd_wa(struct drm_i915_private *i915)
1604 1605
{
	/* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
1606
	if (intel_vtd_active(i915) &&
V
Ville Syrjälä 已提交
1607 1608
	    (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
		drm_info(&i915->drm,
1609
			 "Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
1610 1611 1612 1613 1614 1615
		return true;
	}

	return false;
}

1616 1617 1618 1619 1620 1621 1622 1623 1624
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
{
	if (!fbc)
		return;

	plane->fbc = fbc;
	fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
}

1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652
static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
{
	struct intel_fbc *fbc;

	fbc = kzalloc(sizeof(*fbc), GFP_KERNEL);
	if (!fbc)
		return NULL;

	fbc->i915 = i915;
	INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
	mutex_init(&fbc->lock);

	if (DISPLAY_VER(i915) >= 7)
		fbc->funcs = &ivb_fbc_funcs;
	else if (DISPLAY_VER(i915) == 6)
		fbc->funcs = &snb_fbc_funcs;
	else if (DISPLAY_VER(i915) == 5)
		fbc->funcs = &ilk_fbc_funcs;
	else if (IS_G4X(i915))
		fbc->funcs = &g4x_fbc_funcs;
	else if (DISPLAY_VER(i915) == 4)
		fbc->funcs = &i965_fbc_funcs;
	else
		fbc->funcs = &i8xx_fbc_funcs;

	return fbc;
}

R
Rodrigo Vivi 已提交
1653 1654
/**
 * intel_fbc_init - Initialize FBC
V
Ville Syrjälä 已提交
1655
 * @i915: the i915 device
R
Rodrigo Vivi 已提交
1656 1657 1658
 *
 * This function might be called during PM init process.
 */
V
Ville Syrjälä 已提交
1659
void intel_fbc_init(struct drm_i915_private *i915)
1660
{
1661
	struct intel_fbc *fbc;
P
Paulo Zanoni 已提交
1662

V
Ville Syrjälä 已提交
1663 1664
	if (!drm_mm_initialized(&i915->mm.stolen))
		mkwrite_device_info(i915)->display.has_fbc = false;
1665

V
Ville Syrjälä 已提交
1666 1667
	if (need_fbc_vtd_wa(i915))
		mkwrite_device_info(i915)->display.has_fbc = false;
1668

V
Ville Syrjälä 已提交
1669 1670 1671
	i915->params.enable_fbc = intel_sanitize_fbc_option(i915);
	drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
		    i915->params.enable_fbc);
1672

1673
	if (!HAS_FBC(i915))
1674 1675
		return;

1676 1677 1678
	fbc = intel_fbc_create(i915);
	if (!fbc)
		return;
1679

1680
	/* We still don't have any sort of hardware state readout for FBC, so
1681 1682
	 * deactivate it in case the BIOS activated it to make sure software
	 * matches the hardware state. */
1683 1684
	if (intel_fbc_hw_is_active(fbc))
		intel_fbc_hw_deactivate(fbc);
1685 1686

	i915->fbc = fbc;
1687
}
1688 1689 1690 1691 1692

static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
{
	struct intel_fbc *fbc = m->private;
	struct drm_i915_private *i915 = fbc->i915;
1693
	struct intel_plane *plane;
1694 1695
	intel_wakeref_t wakeref;

1696 1697
	drm_modeset_lock_all(&i915->drm);

1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708
	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
	mutex_lock(&fbc->lock);

	if (fbc->active) {
		seq_puts(m, "FBC enabled\n");
		seq_printf(m, "Compressing: %s\n",
			   yesno(intel_fbc_is_compressing(fbc)));
	} else {
		seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
	}

1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721
	for_each_intel_plane(&i915->drm, plane) {
		const struct intel_plane_state *plane_state =
			to_intel_plane_state(plane->base.state);

		if (plane->fbc != fbc)
			continue;

		seq_printf(m, "%c [PLANE:%d:%s]: %s\n",
			   fbc->state.plane == plane ? '*' : ' ',
			   plane->base.base.id, plane->base.name,
			   plane_state->no_fbc_reason ?: "FBC possible");
	}

1722 1723 1724
	mutex_unlock(&fbc->lock);
	intel_runtime_pm_put(&i915->runtime_pm, wakeref);

1725 1726
	drm_modeset_unlock_all(&i915->drm);

1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778
	return 0;
}

DEFINE_SHOW_ATTRIBUTE(intel_fbc_debugfs_status);

static int intel_fbc_debugfs_false_color_get(void *data, u64 *val)
{
	struct intel_fbc *fbc = data;

	*val = fbc->false_color;

	return 0;
}

static int intel_fbc_debugfs_false_color_set(void *data, u64 val)
{
	struct intel_fbc *fbc = data;

	mutex_lock(&fbc->lock);

	fbc->false_color = val;

	if (fbc->active)
		fbc->funcs->set_false_color(fbc, fbc->false_color);

	mutex_unlock(&fbc->lock);

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(intel_fbc_debugfs_false_color_fops,
			intel_fbc_debugfs_false_color_get,
			intel_fbc_debugfs_false_color_set,
			"%llu\n");

static void intel_fbc_debugfs_add(struct intel_fbc *fbc)
{
	struct drm_i915_private *i915 = fbc->i915;
	struct drm_minor *minor = i915->drm.primary;

	debugfs_create_file("i915_fbc_status", 0444,
			    minor->debugfs_root, fbc,
			    &intel_fbc_debugfs_status_fops);

	if (fbc->funcs->set_false_color)
		debugfs_create_file("i915_fbc_false_color", 0644,
				    minor->debugfs_root, fbc,
				    &intel_fbc_debugfs_false_color_fops);
}

void intel_fbc_debugfs_register(struct drm_i915_private *i915)
{
1779
	struct intel_fbc *fbc = i915->fbc;
1780

1781
	if (fbc)
1782
		intel_fbc_debugfs_add(fbc);
1783
}