Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5e50c3f authored by Jesse Barnes's avatar Jesse Barnes Committed by Eric Anholt
Browse files

drm/i915: provide FBC status in debugfs



Tools like powertop want to check the current FBC status and report it
to the user.  So add a debugfs file indicating whether FBC is enabled,
and if not, why.

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 357b13c3
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -477,6 +477,54 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
	return 0;
}

static int i915_fbc_status(struct seq_file *m, void *unused)
{
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_crtc *crtc;
	drm_i915_private_t *dev_priv = dev->dev_private;
	bool fbc_enabled = false;

	if (!dev_priv->display.fbc_enabled) {
		seq_printf(m, "FBC unsupported on this chipset\n");
		return 0;
	}

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (!crtc->enabled)
			continue;
		if (dev_priv->display.fbc_enabled(crtc))
			fbc_enabled = true;
	}

	if (fbc_enabled) {
		seq_printf(m, "FBC enabled\n");
	} else {
		seq_printf(m, "FBC disabled: ");
		switch (dev_priv->no_fbc_reason) {
		case FBC_STOLEN_TOO_SMALL:
			seq_printf(m, "not enough stolen memory");
			break;
		case FBC_UNSUPPORTED_MODE:
			seq_printf(m, "mode not supported");
			break;
		case FBC_MODE_TOO_LARGE:
			seq_printf(m, "mode too large");
			break;
		case FBC_BAD_PLANE:
			seq_printf(m, "FBC unsupported on plane");
			break;
		case FBC_NOT_TILED:
			seq_printf(m, "scanout buffer not tiled");
			break;
		default:
			seq_printf(m, "unknown reason");
		}
		seq_printf(m, "\n");
	}
	return 0;
}

static int
i915_wedged_open(struct inode *inode,
		 struct file *filp)
@@ -599,6 +647,7 @@ static struct drm_info_list i915_debugfs_list[] = {
	{"i915_delayfreq_table", i915_delayfreq_table, 0},
	{"i915_inttoext_table", i915_inttoext_table, 0},
	{"i915_drpc_info", i915_drpc_info, 0},
	{"i915_fbc_status", i915_fbc_status, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)

+2 −0
Original line number Diff line number Diff line
@@ -1249,6 +1249,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
	/* Leave 1M for line length buffer & misc. */
	compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0);
	if (!compressed_fb) {
		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
		i915_warn_stolen(dev);
		return;
	}
@@ -1256,6 +1257,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
	compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
	if (!compressed_fb) {
		i915_warn_stolen(dev);
		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
		return;
	}

+10 −0
Original line number Diff line number Diff line
@@ -192,6 +192,14 @@ struct intel_device_info {
	u8 cursor_needs_physical : 1;
};

enum no_fbc_reason {
	FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */
	FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */
	FBC_MODE_TOO_LARGE, /* mode too large for compression */
	FBC_BAD_PLANE, /* fbc not supported on plane */
	FBC_NOT_TILED, /* buffer not tiled */
};

typedef struct drm_i915_private {
	struct drm_device *dev;

@@ -597,6 +605,8 @@ typedef struct drm_i915_private {
	u8 cur_delay;
	u8 min_delay;
	u8 max_delay;

	enum no_fbc_reason no_fbc_reason;
} drm_i915_private_t;

/** driver private structure attached to each drm_gem_object */
+5 −0
Original line number Diff line number Diff line
@@ -1188,25 +1188,30 @@ static void intel_update_fbc(struct drm_crtc *crtc,
	if (intel_fb->obj->size > dev_priv->cfb_size) {
		DRM_DEBUG_KMS("framebuffer too large, disabling "
				"compression\n");
		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
		goto out_disable;
	}
	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
	    (mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
		DRM_DEBUG_KMS("mode incompatible with compression, "
				"disabling\n");
		dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE;
		goto out_disable;
	}
	if ((mode->hdisplay > 2048) ||
	    (mode->vdisplay > 1536)) {
		DRM_DEBUG_KMS("mode too large for compression, disabling\n");
		dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE;
		goto out_disable;
	}
	if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
		DRM_DEBUG_KMS("plane not 0, disabling compression\n");
		dev_priv->no_fbc_reason = FBC_BAD_PLANE;
		goto out_disable;
	}
	if (obj_priv->tiling_mode != I915_TILING_X) {
		DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n");
		dev_priv->no_fbc_reason = FBC_NOT_TILED;
		goto out_disable;
	}