drm/i915: Calculate pipe watermarks into CRTC state (v3)
A future patch will calculate these during the atomic 'check' phase
rather than at WM programming time, so let's store the watermark
values we're planning to use in the CRTC state; the values actually
active on the hardware remains in intel_crtc.
While we're at it, do some minor restructuring to keep ILK and SKL
values in a union.
v2: Don't move cxsr_allowed to state (Maarten)
v3: Only calculate watermarks in state. Still keep active watermarks in
intel_crtc itself. (Ville)
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Smoke-tested-by: Paulo Zanoni <przanoni@gmail.com>
Link: http://patchwork.freedesktop.org/patch/59556/
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e01e54a..e5961b2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2274,7 +2274,7 @@
/* Compute the currently _active_ config */
for_each_intel_crtc(dev, intel_crtc) {
- const struct intel_pipe_wm *wm = &intel_crtc->wm.active;
+ const struct intel_pipe_wm *wm = &intel_crtc->wm.active.ilk;
if (!wm->pipe_enabled)
continue;
@@ -2371,7 +2371,9 @@
ret_wm->enable = true;
for_each_intel_crtc(dev, intel_crtc) {
- const struct intel_pipe_wm *active = &intel_crtc->wm.active;
+ const struct intel_crtc_state *cstate =
+ to_intel_crtc_state(intel_crtc->base.state);
+ const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
const struct intel_wm_level *wm = &active->wm[level];
if (!active->pipe_enabled)
@@ -2519,14 +2521,15 @@
/* LP0 register values */
for_each_intel_crtc(dev, intel_crtc) {
+ const struct intel_crtc_state *cstate =
+ to_intel_crtc_state(intel_crtc->base.state);
enum pipe pipe = intel_crtc->pipe;
- const struct intel_wm_level *r =
- &intel_crtc->wm.active.wm[0];
+ const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0];
if (WARN_ON(!r->enable))
continue;
- results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
+ results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime;
results->wm_pipe[pipe] =
(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
@@ -3511,10 +3514,10 @@
skl_allocate_pipe_ddb(cstate, config, ddb);
skl_compute_pipe_wm(cstate, ddb, pipe_wm);
- if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
+ if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
return false;
- intel_crtc->wm.skl_active = *pipe_wm;
+ intel_crtc->wm.active.skl = *pipe_wm;
return true;
}
@@ -3592,7 +3595,8 @@
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct skl_wm_values *results = &dev_priv->wm.skl_results;
- struct skl_pipe_wm pipe_wm = {};
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
struct intel_wm_config config = {};
@@ -3603,10 +3607,10 @@
skl_compute_wm_global_parameters(dev, &config);
- if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
+ if (!skl_update_pipe_wm(crtc, &config, &results->ddb, pipe_wm))
return;
- skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
+ skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
results->dirty[intel_crtc->pipe] = true;
skl_update_other_pipe_wm(dev, crtc, &config, results);
@@ -3655,7 +3659,6 @@
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
- struct intel_pipe_wm pipe_wm = {};
WARN_ON(cstate->base.active != intel_crtc->active);
@@ -3671,12 +3674,13 @@
intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
}
- intel_compute_pipe_wm(cstate, &pipe_wm);
+ intel_compute_pipe_wm(cstate, &cstate->wm.optimal.ilk);
- if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
- return;
+ if (!memcmp(&intel_crtc->wm.active.ilk,
+ &cstate->wm.optimal.ilk,
+ sizeof(cstate->wm.optimal.ilk)));
- intel_crtc->wm.active = pipe_wm;
+ intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
ilk_program_watermarks(dev_priv);
}
@@ -3731,7 +3735,8 @@
struct drm_i915_private *dev_priv = dev->dev_private;
struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
enum pipe pipe = intel_crtc->pipe;
int level, i, max_level;
uint32_t temp;
@@ -3775,6 +3780,8 @@
temp = hw->plane_trans[pipe][PLANE_CURSOR];
skl_pipe_wm_active_state(temp, active, true, true, i, 0);
+
+ intel_crtc->wm.active.skl = *active;
}
void skl_wm_get_hw_state(struct drm_device *dev)
@@ -3794,7 +3801,8 @@
struct drm_i915_private *dev_priv = dev->dev_private;
struct ilk_wm_values *hw = &dev_priv->wm.hw;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_pipe_wm *active = &intel_crtc->wm.active;
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
enum pipe pipe = intel_crtc->pipe;
static const unsigned int wm0_pipe_reg[] = {
[PIPE_A] = WM0_PIPEA_ILK,
@@ -3833,6 +3841,8 @@
for (level = 0; level <= max_level; level++)
active->wm[level].enable = true;
}
+
+ intel_crtc->wm.active.ilk = *active;
}
#define _FW_WM(value, plane) \