[Intel-gfx] [RFC 11/15] drm/i915: Calculate pipe watermark values during atomic check
Matt Roper
matthew.d.roper at intel.com
Wed May 20 19:12:23 PDT 2015
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 at intel.com>
---
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
More information about the Intel-gfx
mailing list