void intel_fbc_pre_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; mutex_lock(&fbc->lock); if (!multiple_pipes_ok(crtc)) { fbc->no_fbc_reason = "more than one pipe active"; goto deactivate; } if (!fbc->enabled || fbc->crtc != crtc) goto unlock; intel_fbc_update_state_cache(crtc); deactivate: intel_fbc_deactivate(dev_priv); unlock: mutex_unlock(&fbc->lock); }
void intel_fbc_pre_update(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; const char *reason = "update pending"; if (!fbc_supported(dev_priv)) return; mutex_lock(&fbc->lock); if (!multiple_pipes_ok(crtc, plane_state)) { reason = "more than one pipe active"; goto deactivate; } if (!fbc->enabled || fbc->crtc != crtc) goto unlock; intel_fbc_update_state_cache(crtc, crtc_state, plane_state); deactivate: intel_fbc_deactivate(dev_priv, reason); unlock: mutex_unlock(&fbc->lock); }
/** * intel_fbc_enable: tries to enable FBC on the CRTC * @crtc: the CRTC * @crtc_state: corresponding &drm_crtc_state for @crtc * @plane_state: corresponding &drm_plane_state for the primary plane of @crtc * * This function checks if the given CRTC was chosen for FBC, then enables it if * possible. Notice that it doesn't activate FBC. It is valid to call * intel_fbc_enable multiple times for the same pipe without an * intel_fbc_disable in the middle, as long as it is deactivated. */ void intel_fbc_enable(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; mutex_lock(&fbc->lock); if (fbc->enabled) { WARN_ON(fbc->crtc == NULL); if (fbc->crtc == crtc) { WARN_ON(!crtc_state->enable_fbc); WARN_ON(fbc->active); } goto out; } if (!crtc_state->enable_fbc) goto out; WARN_ON(fbc->active); WARN_ON(fbc->crtc != NULL); intel_fbc_update_state_cache(crtc, crtc_state, plane_state); if (intel_fbc_alloc_cfb(crtc)) { fbc->no_fbc_reason = "not enough stolen memory"; goto out; } DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe)); fbc->no_fbc_reason = "FBC enabled but not active yet\n"; fbc->enabled = true; fbc->crtc = crtc; out: mutex_unlock(&fbc->lock); }