Skip to content

Commit

Permalink
Reapply "drm/i915: Pass atomic states to fbc update, functions."
Browse files Browse the repository at this point in the history
The patch was reverted as part of the original nonblocking commit
support, but is required for any kind of nonblocking commit.

This is required to let fbc updates run async. It has a lot of
checks whether certain locks are taken, which can be removed when
the relevant states are passed in as pointers.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463490484-19540-17-git-send-email-maarten.lankhorst@linux.intel.com
Reviewed-by: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/28208c38-8738-abdf-0cce-8d8f266b9c28@linux.intel.com
  • Loading branch information
Maarten Lankhorst authored and Daniel Vetter committed Jun 16, 2016
1 parent ea0000f commit faf68d9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
8 changes: 5 additions & 3 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -4641,7 +4641,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
struct intel_plane_state *old_primary_state =
to_intel_plane_state(old_pri_state);

intel_fbc_pre_update(crtc);
intel_fbc_pre_update(crtc, pipe_config, primary_state);

if (old_primary_state->visible &&
(modeset || !primary_state->visible))
Expand Down Expand Up @@ -11728,7 +11728,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,

crtc->primary->fb = fb;
update_state_fb(crtc->primary);
intel_fbc_pre_update(intel_crtc);

intel_fbc_pre_update(intel_crtc, intel_crtc->config,
to_intel_plane_state(primary->state));

work->pending_flip_obj = obj;

Expand Down Expand Up @@ -13825,7 +13827,7 @@ static int intel_atomic_commit(struct drm_device *dev,

if (crtc->state->active &&
drm_atomic_get_existing_plane_state(state, crtc->primary))
intel_fbc_enable(intel_crtc);
intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));

if (crtc->state->active)
drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
Expand Down
8 changes: 6 additions & 2 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1431,11 +1431,15 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
struct drm_atomic_state *state);
bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
void intel_fbc_pre_update(struct intel_crtc *crtc);
void intel_fbc_pre_update(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
void intel_fbc_post_update(struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv);
void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv);
void intel_fbc_enable(struct intel_crtc *crtc);
void intel_fbc_enable(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
void intel_fbc_disable(struct intel_crtc *crtc);
void intel_fbc_global_disable(struct drm_i915_private *dev_priv);
void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
Expand Down
39 changes: 18 additions & 21 deletions drivers/gpu/drm/i915/intel_fbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,20 +481,18 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
intel_fbc_hw_deactivate(dev_priv);
}

static bool multiple_pipes_ok(struct intel_crtc *crtc)
static bool multiple_pipes_ok(struct intel_crtc *crtc,
struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_plane *primary = crtc->base.primary;
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
enum pipe pipe = crtc->pipe;

/* Don't even bother tracking anything we don't need. */
if (!no_fbc_on_multiple_pipes(dev_priv))
return true;

WARN_ON(!drm_modeset_is_locked(&primary->mutex));

if (to_intel_plane_state(primary->state)->visible)
if (plane_state->visible)
fbc->visible_pipes_mask |= (1 << pipe);
else
fbc->visible_pipes_mask &= ~(1 << pipe);
Expand Down Expand Up @@ -709,21 +707,16 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
return effective_w <= max_w && effective_h <= max_h;
}

static void intel_fbc_update_state_cache(struct intel_crtc *crtc)
static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache;
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane_state *plane_state =
to_intel_plane_state(crtc->base.primary->state);
struct drm_framebuffer *fb = plane_state->base.fb;
struct drm_i915_gem_object *obj;

WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex));

cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
cache->crtc.hsw_bdw_pixel_rate =
Expand Down Expand Up @@ -888,7 +881,9 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1,
return memcmp(params1, params2, sizeof(*params1)) == 0;
}

void intel_fbc_pre_update(struct intel_crtc *crtc)
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 = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc;
Expand All @@ -898,15 +893,15 @@ void intel_fbc_pre_update(struct intel_crtc *crtc)

mutex_lock(&fbc->lock);

if (!multiple_pipes_ok(crtc)) {
if (!multiple_pipes_ok(crtc, plane_state)) {
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);
intel_fbc_update_state_cache(crtc, crtc_state, plane_state);

deactivate:
intel_fbc_deactivate(dev_priv);
Expand Down Expand Up @@ -1090,7 +1085,9 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
* 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)
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 = crtc->base.dev->dev_private;
struct intel_fbc *fbc = &dev_priv->fbc;
Expand All @@ -1103,19 +1100,19 @@ void intel_fbc_enable(struct intel_crtc *crtc)
if (fbc->enabled) {
WARN_ON(fbc->crtc == NULL);
if (fbc->crtc == crtc) {
WARN_ON(!crtc->config->enable_fbc);
WARN_ON(!crtc_state->enable_fbc);
WARN_ON(fbc->active);
}
goto out;
}

if (!crtc->config->enable_fbc)
if (!crtc_state->enable_fbc)
goto out;

WARN_ON(fbc->active);
WARN_ON(fbc->crtc != NULL);

intel_fbc_update_state_cache(crtc);
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;
Expand Down

0 comments on commit faf68d9

Please sign in to comment.