Beispiel #1
0
static bool intel_fbc_can_choose(struct intel_crtc *crtc)
{
	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
	struct intel_fbc *fbc = &dev_priv->fbc;
	bool enable_by_default = IS_BROADWELL(dev_priv);

	if (intel_vgpu_active(dev_priv->dev)) {
		fbc->no_fbc_reason = "VGPU is active";
		return false;
	}

	if (i915.enable_fbc < 0 && !enable_by_default) {
		fbc->no_fbc_reason = "disabled per chip default";
		return false;
	}

	if (!i915.enable_fbc) {
		fbc->no_fbc_reason = "disabled per module param";
		return false;
	}

	if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) {
		fbc->no_fbc_reason = "no enabled pipes can have FBC";
		return false;
	}

	if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) {
		fbc->no_fbc_reason = "no enabled planes can have FBC";
		return false;
	}

	return true;
}
Beispiel #2
0
/**
 * intel_fbc_init - Initialize FBC
 * @dev_priv: the i915 device
 *
 * This function might be called during PM init process.
 */
void intel_fbc_init(struct drm_i915_private *dev_priv)
{
	struct intel_fbc *fbc = &dev_priv->fbc;
	enum pipe pipe;

	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
	INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
	mutex_init(&fbc->lock);
	fbc->enabled = false;
	fbc->active = false;
	fbc->work.scheduled = false;

	if (need_fbc_vtd_wa(dev_priv))
		mkwrite_device_info(dev_priv)->has_fbc = false;

	i915_modparams.enable_fbc = intel_sanitize_fbc_option(dev_priv);
	DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n",
		      i915_modparams.enable_fbc);

	if (!HAS_FBC(dev_priv)) {
		fbc->no_fbc_reason = "unsupported by this chipset";
		return;
	}

	for_each_pipe(dev_priv, pipe) {
		fbc->possible_framebuffer_bits |=
				INTEL_FRONTBUFFER_PRIMARY(pipe);

		if (fbc_on_pipe_a_only(dev_priv))
			break;
	}
Beispiel #3
0
/**
 * intel_fbc_choose_crtc - select a CRTC to enable FBC on
 * @dev_priv: i915 device instance
 * @state: the atomic state structure
 *
 * This function looks at the proposed state for CRTCs and planes, then chooses
 * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to
 * true.
 *
 * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe
 * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc.
 */
void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
			   struct intel_atomic_state *state)
{
	struct intel_fbc *fbc = &dev_priv->fbc;
	struct intel_plane *plane;
	struct intel_plane_state *plane_state;
	bool crtc_chosen = false;
	int i;

	mutex_lock(&fbc->lock);

	/* Does this atomic commit involve the CRTC currently tied to FBC? */
	if (fbc->crtc &&
	    !intel_atomic_get_new_crtc_state(state, fbc->crtc))
		goto out;

	if (!intel_fbc_can_enable(dev_priv))
		goto out;

	/* Simply choose the first CRTC that is compatible and has a visible
	 * plane. We could go for fancier schemes such as checking the plane
	 * size, but this would just affect the few platforms that don't tie FBC
	 * to pipe or plane A. */
	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
		struct intel_crtc_state *crtc_state;
		struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);

		if (!plane_state->base.visible)
			continue;

		if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A)
			continue;

		if (fbc_on_plane_a_only(dev_priv) && plane->i9xx_plane != PLANE_A)
			continue;

		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);

		crtc_state->enable_fbc = true;
		crtc_chosen = true;
		break;
	}

	if (!crtc_chosen)
		fbc->no_fbc_reason = "no suitable CRTC for FBC";

out:
	mutex_unlock(&fbc->lock);
}
Beispiel #4
0
/**
 * intel_fbc_init - Initialize FBC
 * @dev_priv: the i915 device
 *
 * This function might be called during PM init process.
 */
void intel_fbc_init(struct drm_i915_private *dev_priv)
{
	struct intel_fbc *fbc = &dev_priv->fbc;
	enum pipe pipe;

	INIT_WORK(&fbc->work.work, intel_fbc_work_fn);
	mutex_init(&fbc->lock);
	fbc->enabled = false;
	fbc->active = false;
	fbc->work.scheduled = false;

	if (!HAS_FBC(dev_priv)) {
		fbc->no_fbc_reason = "unsupported by this chipset";
		return;
	}

	for_each_pipe(dev_priv, pipe) {
		fbc->possible_framebuffer_bits |=
				INTEL_FRONTBUFFER_PRIMARY(pipe);

		if (fbc_on_pipe_a_only(dev_priv))
			break;
	}