Calculate pipe watermarks during atomic calculation phase, based on the contents of the atomic transaction's state structure. FIXME: For now we just dump this in a temporary structure and don't do anything with it except compare it to the values we re-calculate later. Ultimately we should squash the next patch into this one once we're sure this is really working as expected. Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_atomic.c | 29 +++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 5 +++++ drivers/gpu/drm/i915/intel_pm.c | 6 +++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index df5673f..214ce76 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -562,6 +562,9 @@ struct drm_i915_display_funcs { int target, int refclk, struct dpll *match_clock, struct dpll *best_clock); + int (*compute_pipe_wm)(struct drm_crtc *crtc, + struct drm_atomic_state *state, + void *target); void (*update_wm)(struct drm_crtc *crtc); void (*update_sprite_wm)(struct drm_plane *plane, struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 7ed8033..db349dd 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -176,8 +176,13 @@ int intel_atomic_commit(struct drm_device *dev, continue; } - to_intel_crtc(crtc)->config->scaler_state = - to_intel_crtc_state(state->crtc_states[i])->scaler_state; +#define STATE_SWAP(x) to_intel_crtc(crtc)->config->x = \ + to_intel_crtc_state(state->crtc_states[i])->x; + + STATE_SWAP(scaler_state); + STATE_SWAP(wm); + +#undef STATE_SWAP if (INTEL_INFO(dev)->gen >= 9) skl_detach_scalers(to_intel_crtc(crtc)); @@ -421,3 +426,23 @@ int intel_atomic_setup_scalers(struct drm_device *dev, return 0; } + +/* + * intel_check_crtc: Check CRTC state + */ +int +intel_check_crtc(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_crtc_state *intel_state = to_intel_crtc_state(state); + int ret; + + if (!dev_priv->display.compute_pipe_wm) + return 0; + + ret = dev_priv->display.compute_pipe_wm(crtc, state->state, + &intel_state->wm.tmp); + + return ret; +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f4398a7..76affba 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11096,6 +11096,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = { .load_lut = intel_crtc_load_lut, .atomic_begin = intel_begin_crtc_commit, .atomic_flush = intel_finish_crtc_commit, + .atomic_check = intel_check_crtc, }; /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4ae109c..6ca3c06 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -464,6 +464,9 @@ struct intel_crtc_state { struct intel_crtc_scaler_state scaler_state; struct { + /* tmp wm */ + struct intel_pipe_wm tmp; + /* final, target watermarks for state */ union { struct intel_pipe_wm ilk; @@ -1424,6 +1427,8 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state, int intel_atomic_setup_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); +int intel_check_crtc(struct drm_crtc *crtc, + struct drm_crtc_state *state); /* intel_atomic_plane.c */ struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 789b4fe..017b184 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2074,8 +2074,9 @@ static void ilk_compute_wm_config(struct drm_device *dev, /* Compute new watermarks for the pipe */ static int ilk_compute_pipe_wm(struct drm_crtc *crtc, struct drm_atomic_state *state, - struct intel_pipe_wm *pipe_wm) + void *target) { + struct intel_pipe_wm *pipe_wm = target; struct drm_device *dev = crtc->dev; const struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -3514,6 +3515,8 @@ static void ilk_update_wm(struct drm_crtc *crtc) struct intel_pipe_wm pipe_wm = {}; ilk_compute_pipe_wm(crtc, NULL, &pipe_wm); + WARN(memcmp(&cstate->wm.tmp, &pipe_wm, sizeof(pipe_wm)) != 0, + "Pre-computed atomic watermark values do not match final values!"); if (!memcmp(&cstate->wm.target.ilk, &pipe_wm, sizeof(pipe_wm))) return; @@ -6655,6 +6658,7 @@ void intel_init_pm(struct drm_device *dev) dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.update_sprite_wm = ilk_update_sprite_wm; + dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; } else { DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); -- 1.8.5.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx